diff --git a/AGENTS.md b/AGENTS.md index 9aa9e6a9e..bd7a2e6ab 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -195,14 +195,14 @@ Build complete, long-term solutions, not MVPs or local workarounds. A broad chan - **Use `Sleep::usleep()` / `Sleep::sleep()` for delays in source code** — `Sleep` is fakeable in tests. Use raw `sleep()` / `usleep()` only where real time must pass, such as test harnesses and external-process polling. - **Use `xxh128` for internal non-cryptographic hashing** — cache and context keys, content checksums, and change detection. It is faster than `sha256`, which is reserved for trust boundaries: stored credential digests, signatures, and anything an attacker gains by forging. Seed it when the hashed value comes from user input, as `SwooleStore` does for its physical table keys. - **Use immutable dates by default** — Hypervel defaults to `Hypervel\Support\CarbonImmutable`, including where Laravel uses mutable Carbon. Create public or application-configurable dates through the `Date` facade or date helpers, and use exact `CarbonImmutable` for framework-owned internal or held values. Type configurable Carbon boundaries as `CarbonInterface` and native or third-party boundaries as `DateTimeInterface`. Capture the return value of every date modifier whose result must persist. Use `Hypervel\Support\Carbon` only for explicit mutable opt-out or conversion behavior. -- **Use typed config getters and avoid duplicate defaults** — prefer `$config->string()`, `$config->integer()`, `$config->float()`, `$config->boolean()`, and `$config->array()` over `$config->get()` for values that cannot be null. Framework and package defaults are shallow-merged with application config. `mergeableOptions()` is only for named groups such as connections or stores: application entries replace matching defaults, while other default entries remain. Other nested arrays are replaced as a whole. Keep a fallback when a setting inside one of those replaced arrays is intentionally optional. +- **Use typed config getters and avoid duplicate defaults** — prefer `$config->string()`, `$config->integer()`, `$config->float()`, `$config->boolean()`, and `$config->array()` over `$config->get()` for values that cannot be null. Do not pass a code-level fallback when the framework or package config defines the key; missing or misspelled keys should fail loudly instead of silently using a second default. Framework and package defaults are shallow-merged with application config. `mergeableOptions()` is only for named groups such as connections or stores: application entries replace matching defaults, while other default entries remain. Other nested arrays are replaced as a whole. Keep a fallback when a setting inside one of those replaced arrays is intentionally optional. - **Env var naming** — Ported config keeps upstream names. New Hypervel-specific settings should use the established prefix for the package or subsystem that owns the value (`SERVER_`, `CACHE_`, `REDIS_`, etc.). Determine ownership semantically, not from the config filename: aggregate files such as `app.php` contain multiple domains, and `APP_` is for genuinely application-wide settings. If a value mirrors another config key, reuse that key's environment variable instead of defining a duplicate. - **Use `resolve...Using` for Hypervel-owned config resolvers** — prefer this naming for callbacks that resolve config-derived values, unless an established Laravel domain convention already exists, such as `redirectUsing()`. - **Always use American English spelling** — E.g., "behavior" vs "behaviour", "utilize" vs "utilise". ## Container -Hypervel's container keeps Laravel's API surface — `bind()`, `singleton()`, `scoped()`, `instance()`, aliases, contextual bindings — with resolution adapted for long-lived Swoole workers. `make()` and `get()` resolve identically; `get()` is just the PSR-compliant exception wrapper. Use `make()`, and use it instead of array access too: `offsetGet()` always returns `mixed`, while `make()` carries class-string generics phpstan can follow, `make()` can take parameters, and `$app[$key] = $value` is a hidden `bind()`. Converting `$app['...']` in ported code to `make()` is an approved modernization (see Policy under Porting Packages). `Container::getInstance()` auto-creates via `??= new static()`, so it always returns a container. +Hypervel's container keeps Laravel's named API surface — `bind()`, `singleton()`, `scoped()`, `instance()`, aliases, contextual bindings — with resolution adapted for long-lived Swoole workers. Container ArrayAccess and dynamic service properties are intentionally unsupported. `make()` and `get()` resolve identically; `get()` is the PSR-compliant exception wrapper. `Container::getInstance()` auto-creates via `??= new static()`, so it always returns a container. ### Resolution semantics vs Laravel @@ -727,7 +727,7 @@ Full PHPStan runs through `composer fix` at checkpoints. During implementation, When porting Laravel packages, whether first-party or third-party, keep them as close to 1:1 with upstream as possible so future changes are easy to merge. The exceptions are: - Modernizing PHP types, including native parameter, return, property, and class-constant types, plus other appropriate PHP 8.4+ features, strict types, and strict comparisons - Converting mutable Laravel date construction to Hypervel's immutable date conventions, typing configurable factory output as `CarbonInterface`, and capturing date-modifier return values -- Converting container array access (`$app['events']`) to `make()`, and untyped `$config->get()` calls to the typed getters where the key isn't nullable (see Container and the typed-getter rule under Development Conventions) +- Converting container array access (`$app['events']`) and dynamic service-property access (`$app->events`) in ported code to named container methods, and untyped `$config->get()` calls to typed getters where the key isn't nullable (see Container and the typed-getter rule under Development Conventions) - Adding Laravel-style title docblocks to methods (not classes — see Development Conventions) - For ported Laravel packages: making them coroutine-safe, adding Swoole performance enhancements (e.g., static property caching), making them pass PHPStan - Not porting upstream framework-specific integrations that only make sense in the source framework (for example packages, drivers) unless Hypervel intentionally has an equivalent surface @@ -880,6 +880,7 @@ Tests for these features should be **removed** (not commented out) without askin - **Databases:** SQL Server, MongoDB, DynamoDB — Hypervel only supports MySQL, MariaDB, PostgreSQL, and SQLite - **Cache drivers:** Memcached, DynamoDB, MongoDB - **Dynamic connections:** `DB::build()`, `DB::connectUsing()` — incompatible with Swoole connection pooling +- **Container access:** ArrayAccess and dynamic service properties This list is exhaustive. Any other missing functionality requires investigation and reporting per When to Stop and Report. @@ -894,5 +895,5 @@ This list is exhaustive. Any other missing functionality requires investigation 7. Fix mock types (PDO, QueryBuilder, Grammar, etc.) 8. Add `->andReturnSelf()` to chained method mocks 9. Use a test-specific namespace only when helper classes have generic, collision-prone names — already-specific helper names do not need extra namespace ceremony. -10. Remove tests for unsupported features (SQL Server/MongoDB/DynamoDB databases, Memcached/DynamoDB/MongoDB cache, dynamic connections) +10. Remove tests only for the approved unsupported features listed above 11. Run tests and fix any remaining type errors diff --git a/docs/plans/2026-08-14-1721-container-named-api-and-array-access-removal.md b/docs/plans/2026-08-14-1721-container-named-api-and-array-access-removal.md new file mode 100644 index 000000000..ce2935ae8 --- /dev/null +++ b/docs/plans/2026-08-14-1721-container-named-api-and-array-access-removal.md @@ -0,0 +1,385 @@ +# Container named API and ArrayAccess removal plan + +## Status and objective + +Design consensus and peer plan review are complete; `claude-array-access` signed off after three review passes. Implementation is authorized and in progress. + +Hypervel 0.4 will intentionally omit Laravel's container `ArrayAccess` API and the equivalent dynamic service properties. Container registration, lookup, and lifecycle changes will use named methods throughout the framework and its tests. The change also tightens the facade application boundary to the container contract, fixes temporary override cleanup, and records the public incompatibility where users and future Laravel ports will find it. + +The owner approved the exact test deletion and consolidation list, applied the protected `AGENTS.md` update after peer signoff, and approved removing the inherited scalar `concurrency.driver` compatibility path. + +## Final design + +### Public contract + +- `Hypervel\Contracts\Container\Container` extends only PSR-11 `ContainerInterface`. `Hypervel\Contracts\Foundation\Application` inherits this change transitively. +- `Hypervel\Container\Container` implements only the Hypervel container contract. Remove its `ArrayAccess` import, interface, four `offset*` methods, and `__get` / `__set` service accessors. +- Do not add a deprecation shim, compatibility trait, helper, or custom error. Native PHP errors and warnings expose unsupported array and dynamic-property use without a compatibility fallback. +- Do not add `forgetBinding()`. No production caller needs arbitrary binding deletion, and the removed `offsetUnset()` semantics are not a sound public operation: they clear selected binding, resolution, lifecycle, instance, and alias state while leaving tags, extenders, contextual bindings, rebound callbacks, and aliases that may target the canonical key. +- Keep `make()` for Hypervel resolution and `get()` for PSR-11 callers. Use `bound()` for Hypervel binding checks and `has()` where the variable is intentionally PSR-11-shaped. + +The concrete class keeps a concise marker at the former offset-method location: + +```php +// Hypervel intentionally omits container array and dynamic property access. +// Use named methods so resolution and binding lifecycles remain explicit. +``` + +This is the source marker required for an intentionally omitted Laravel feature. `flushState()` remains the last method after the removed trailing offset and magic-method block. + +### Why this is the clean boundary + +- `ArrayAccess` is suitable for real map or collection objects; it is not deprecated or generally bad PHP. The problem is the container mapping: reads perform resolution, writes silently select transient binding semantics, and unset mutates several lifecycle stores. +- `make()` carries Hypervel's conditional class-string generic return. `offsetGet(): mixed` loses that information and cannot accept resolution parameters. +- `$app[$key] = $value` hides whether the caller intends a transient factory or a shared existing value. Named `bind()` and `instance()` make that lifecycle choice reviewable. +- `$app->service` and `$app->service = $value` are even less discoverable and can be confused with declared properties. +- PSR-11 exposes `get()` and `has()`. Current PHP-DI, Symfony DI, and League Container implementations do not implement `ArrayAccess`. +- Laravel 13 retains ArrayAccess and dynamic properties on its concrete container, so documentation must not call them deprecated. Laravel's contract omits `ArrayAccess`, its current container guide documents named methods rather than array or dynamic-property access, and Laravel rejected adding `ArrayAccess` to the contract because it is a separate concern that is not required for a container. +- Hypervel 0.4 is the correct hard-break point. A compatibility layer would allow ported and application code to keep introducing the syntax this design is meant to remove. + +### Named-method migration rules + +Audit every candidate; do not bulk replace it. + +| Existing use | Replacement | +|---|---| +| `$container[$abstract]` | `$container->make($abstract)` | +| `isset($container[$abstract])` | `$container->bound($abstract)`, or `has()` for an intentionally PSR-11-typed value | +| `$container[$abstract] = $closure` | `$container->bind($abstract, $closure)` | +| `$container[$abstract] = $objectOrValue` | `$container->instance($abstract, $objectOrValue)` when the caller supplies one shared value; retain `bind(fn () => $value)` only when transient binding and rebinding behavior are intentional | +| `unset($container[$abstract])` | Refactor around the caller's actual lifecycle. The verified temporary overrides use `forgetInstance()` | +| `$container->service` | `$container->make('service')` | +| `$container->service = $value` | Explicit `instance()` or `bind()` after reviewing lifetime intent | + +For config, resolve the repository explicitly. Use typed getters only when presence and type are guaranteed. Keep `get()` plus the existing fallback or type guard when current behavior accepts a missing or wrong-typed value. When `null` intentionally selects or disables behavior, preserve that meaning and ensure the null branch has a focused behavioral test. + +`offsetSet()` currently does fire rebound callbacks: `bind()` calls `registerBinding()`, which calls `rebound()` for an already-resolved abstract. Conversions that must preserve offset assignment semantics use `bind()`, not `instance()`. + +## Implementation + +### 1. Remove the API at its owning boundary + +Update one file at a time: + +1. `src/contracts/src/Container/Container.php` + - Remove the `ArrayAccess` import and parent interface. + - Keep the existing PSR and Hypervel named method surface unchanged. +2. `src/container/src/Container.php` + - Remove the `ArrayAccess` import and implemented interface. + - Remove `offsetExists()`, `offsetGet()`, `offsetSet()`, `offsetUnset()`, `__get()`, and `__set()`. + - Add the concise intentional-removal marker at the former method block. + - Do not alter `bound()`, `resolved()`, `bind()`, `instance()`, `forgetInstance()`, alias handling, or cached-instance internals as part of the removal. + +The `isset(...) || array_key_exists(...)` pairs in `bound()`, `resolved()`, and `resolve()` remain. They deliberately support `instance($abstract, null)` while retaining an `isset()` fast path. + +### 2. Convert production consumers + +The verified production migration surface is grouped below. Each file must be read, changed, and checked separately. A name-independent receiver sweep found three caller shapes missed by the original app/container-name search: 21 `$this->hypervel[...]` reads across 13 console-command files, 10 `$this[...]` accesses in `Application`, and one local `$hypervel[...]` read in Testbench `UsesVendor`. The two other `$this[...]` source hits are inside the container magic accessors removed at the owning boundary. + +| Area | Files | Required conversion | +|---|---|---| +| Cache console | `src/cache/src/Console/ClearCommand.php` | Resolve events through `$this->hypervel->make()`. | +| Concurrency | `src/concurrency/src/ConcurrencyManager.php` | Resolve config explicitly and apply the approved default/per-driver key correction described below. | +| Console | `src/console/src/Concerns/ConfiguresPrompts.php`, `src/console/src/Concerns/CreatesMatchingTest.php` | Resolve validator and path services through `$this->hypervel->make()`. | +| Database | `src/database/src/Capsule/Manager.php`, `src/database/src/Console/Migrations/MigrateCommand.php`, `src/database/src/Console/Migrations/RefreshCommand.php`, `src/database/src/Console/WipeCommand.php`, `src/database/src/DatabaseServiceProvider.php`, `src/database/src/Migrations/Migrator.php` | Use `make()` for config, database, filesystem, event, migration, and dispatcher services. Console commands use `$this->hypervel->make()`. Preserve config repository writes as config writes. | +| Filesystem | `src/filesystem/src/FilesystemManager.php` | Resolve the URL service with `make()`. | +| Foundation | `src/foundation/src/Application.php`, `src/foundation/src/Bootstrap/HandleExceptions.php`, `src/foundation/src/Console/ConfigCacheCommand.php`, `src/foundation/src/Console/EnvironmentCommand.php`, `src/foundation/src/Console/Kernel.php`, `src/foundation/src/Console/RouteCacheCommand.php`, `src/foundation/src/Console/RouteListCommand.php`, `src/foundation/src/Http/Kernel.php`, `src/foundation/src/Providers/FoundationServiceProvider.php`, `src/foundation/src/Support/Providers/RouteServiceProvider.php` | Replace config, event, environment, file, router, and URL-generator reads with named methods. Console commands use `$this->hypervel->make()`; `Application` follows the lifecycle audit below. | +| Foundation testing | `src/foundation/src/Testing/Concerns/InteractsWithAuthentication.php`, `src/foundation/src/Testing/Concerns/InteractsWithSession.php`, `src/foundation/src/Testing/Concerns/MakesHttpRequests.php`, `src/foundation/src/Testing/DatabaseTruncation.php`, `src/foundation/src/Testing/WithConsoleEvents.php` | Use named service reads. Apply the temporary middleware override fix described below. | +| Logging | `src/log/src/Context/ContextServiceProvider.php`, `src/log/src/LogManager.php` | Resolve events with `make()`. | +| Queue | `src/queue/src/Console/ClearCommand.php`, `src/queue/src/Console/RetryCommand.php`, `src/queue/src/Console/WorkCommand.php`, `src/queue/src/QueueManager.php`, `src/queue/src/SyncQueue.php` | Resolve event, queue, and cache services with `make()`; console commands use `$this->hypervel->make()`. | +| Sentry | `src/sentry/src/SentryServiceProvider.php` | Apply the typed user-configuration conversion below. | +| Support | `src/support/src/ServiceProvider.php` | Replace dynamic config-property access using the behavior-preserving snippet below. | +| Support facades | `src/support/src/Facades/Cookie.php`, `src/support/src/Facades/Date.php`, `src/support/src/Facades/Facade.php`, `src/support/src/Facades/Queue.php`, `src/support/src/Facades/Schema.php`, `src/support/src/Facades/Storage.php` | Use named container methods and apply the typed facade boundary described below. | +| Testbench | `src/testbench/src/Attributes/UsesVendor.php`, `src/testbench/src/Concerns/HandlesDatabases.php`, `src/testbench/src/Concerns/InteractsWithPublishedFiles.php` | Resolve the cloned application's guaranteed vendor-symlink flag, events, and files with `make()`. Remove `UsesVendor`'s unreachable null fallback after `CreateVendorSymlink::handle()` registers the boolean instance. | +| Testing | `src/testing/src/Concerns/TestCaches.php`, `src/testing/src/Concerns/TestViews.php`, `src/testing/src/PendingCommand.php` | Resolve config/compiler services by method and apply the temporary console-output override fix below. | +| Validation | `src/validation/src/ValidationServiceProvider.php` | Replace offset reads with `make()` and the two-entry `isset` check with explicit `bound()` checks before resolving. | + +Keep these verified ordinary-array uses unchanged even though the variables resemble containers: + +- `src/reverb/src/ConfigApplicationProvider.php` +- `src/server/src/ServerManager.php` +- `src/coordinator/src/CoordinatorManager.php` +- `src/di/src/Aop/AspectManager.php` +- `src/foundation/src/PackageManifest.php` (`$hypervel` is the validated Composer `extra.hypervel` array) + +#### Console command application access + +`Command::$hypervel` is nullable during construction, but `Console\Application::addCommand()` and `freshCommandForRun()` inject it before command execution. `Command` and its subclasses already use the direct property throughout their execution paths, matching Laravel's command idiom. Convert offset reads directly to `$this->hypervel->make(...)`; do not introduce `getHypervel()` only for converted calls and create two styles in one method. When the same resolved service is reused, store that service in a local variable instead of aliasing the application property. + +#### Application self-access + +`Hypervel\Foundation\Application` extends the container, so its ten `$this[...]` uses are container access even though they have no receiver variable name. Convert event and environment reads to `$this->make(...)`. In `detectEnvironment()`, register the detected string as the shared application environment and preserve the return value: + +```php +return $this->instance('env', (new EnvironmentDetector)->detect($callback, $args)); +``` + +`instance()` returns the supplied value and expresses the environment's actual shared-value lifetime. It replaces the current hidden `bind('env', fn () => $value)` selected by offset assignment. Extend one existing `detectEnvironment()` integration case to assert that `environment()` returns the detected value; do not add a separate test method. + +#### Inherited concurrency configuration defect + +`ConcurrencyManager` inherits three incompatible uses of `concurrency.driver` from Laravel: + +- `getDefaultInstance()` reads `concurrency.driver` as a legacy scalar fallback after `concurrency.default`. +- `setDefaultInstance()` writes both `concurrency.default` and scalar `concurrency.driver`. +- `getInstanceConfig()` reads `concurrency.driver.{$name}` as a per-driver array. + +Writing the default can therefore replace the entire per-driver map. The shipped Hypervel and Laravel configs define only `concurrency.default`, and current Laravel contains the same collision. Laravel history shows the shipped configuration moving from `driver` to `default` in `50205f4a13`, followed by `15e0224750` (`support driver`) adding the dual scalar read/write; the earlier `fbef34c77b` index change also explains why per-driver configuration now occupies the singular `driver` key. Hypervel 0.4 has never shipped the legacy scalar key. `AGENTS.md` says not to port backwards-compatibility shims for versions or features Hypervel does not support, so removing this path follows existing porting policy rather than introducing a novel divergence. + +The owner approved the clean 0.4 behavior: use `concurrency.default` exclusively for the default, read it with the typed `string()` getter without duplicating the shipped config default in code, and make `setDefaultInstance()` write only that key. A missing or misspelled merged key must fail at the config boundary instead of silently selecting `coroutine`. Keep the existing `concurrency.driver.{$name}` location for per-driver configuration so fixing the collision does not invent a second schema change. Add a regression proving that changing the default does not overwrite configured per-driver data. + +#### Typed Sentry configuration + +`SentryServiceProvider::getUserConfig()` promises an array. Resolve config explicitly and use: + +```php +return $this->app->make('config')->array(static::$abstract); +``` + +Remove the current `empty()` ternary. `register()` merges the package config before this method is called, so the root key is guaranteed and must not duplicate the package default in code. A missing or invalid non-array value now fails at the typed configuration boundary with `InvalidArgumentException` instead of being hidden or flowing to a return-type `TypeError`. + +#### View-path compatibility + +`ServiceProvider::loadViewsFrom()` currently skips a missing or non-array `view.paths` value. `Repository::array()` would throw and change that behavior. Use: + +```php +$config = $this->app->make('config'); + +if (is_array($viewPaths = $config->get('view.paths'))) { + foreach ($viewPaths as $viewPath) { +``` + +The single `is_array()` check covers the current missing-value case because `is_array(null)` is false. + +#### Temporary middleware overrides + +`withoutMiddleware()` installs either `middleware.disable` or selected fake middleware through `instance()`. Replace `withMiddleware()`'s unsets with `forgetInstance()`. + +This is a bug fix as well as an API conversion. An explicit binding survives `instance()`, but current `offsetUnset()` deletes it. `forgetInstance()` removes the fake and restores the original binding and lifecycle. It also deliberately preserves the abstract's `resolved()` history, so a later `bind()` or `extend()` may fire rebinding callbacks where destructive offset-unset cleanup did not. + +Add one regression to `tests/Foundation/Testing/Concerns/MakesHttpRequestsTest.php`: pre-bind middleware with behavior that cannot be recovered by zero-configuration construction, call `withoutMiddleware($class)` and `withMiddleware($class)`, then prove the original binding remains and resolves again. Keep the existing formerly-unbound and global-disable cases. + +#### Temporary console output + +`PendingCommand::mockConsoleOutput()` creates one mock object. Register it with `instance(OutputStyle::class, $mock)` and replace the `finally` cleanup with `forgetInstance(OutputStyle::class)`. + +Do not add a dedicated test. Existing `tests/Console/ArtisanCommandTest.php` console paths exercise the cleanup and assert that `OutputStyle::class` is no longer bound. `ContainerTest::testForgettingTemporaryInstanceRestoresScopedLifecycle` already proves that an instance override can be forgotten while the original scoped registration survives. + +### 3. Type the facade application boundary + +`Facade` stops accepting an untyped ArrayAccess duck type once resolution uses `make()`. Make the real requirement native and nullable: + +```php +protected static ?ContainerContract $app = null; + +public static function getFacadeApplication(): ?ContainerContract; + +public static function setFacadeApplication(?ContainerContract $app): void; +``` + +`resolveFacadeInstance()` uses `static::$app->make($name)`. The existing truthy guard narrows the nullable property there. + +Eight nullable-boundary sites deliberately fail if no facade application has been set. Preserve that fail-fast behavior without guards or a throwing helper. At each site, copy `static::$app` or `static::getFacadeApplication()` to a local variable narrowed with `/** @var ContainerContract $app */`, then use the container: + +- `Facade.php`: `resolved()` +- `Cookie.php`: `has()` and `get()` +- `Schema.php`: `connection()` +- `Storage.php`: `fake()`, `persistentFake()`, and `buildDiskConfiguration()` +- `Queue.php`: the `QueueFake` constructor call in `fake()` + +Do not make `QueueFake` nullable. `Queue::fake()` already requires a facade root and therefore a container. + +`Date::resolveFacadeInstance()` replaces its nested app/offset `isset` with the equivalent `static::$app === null || ! static::$app->bound($name)` fallback condition. + +In `Storage::fake()` and `persistentFake()`, read the guaranteed default disk with the config repository's `string('filesystems.default')` getter. `buildDiskConfiguration()` must keep tolerant nested config behavior: + +```php +$originalConfig = $app->make('config')->get("filesystems.disks.{$disk}") ?? []; +``` + +Do not use `array(..., [])`; the existing code does not eagerly reject a non-array value before reading its optional `throw` offset. + +Update `tests/Support/SupportFacadeTest.php` deliberately: + +- `ApplicationStub` extends concrete `Hypervel\Container\Container` instead of implementing `ArrayAccess`. +- Replace the ArrayAccess-era `setAttributes()` helper with `setInstances()`, registering each supplied key through `instance()`. +- `CountingApplicationStub` counts `make()` calls using the exact parent signature `public function make(string $abstract, array $parameters = []): mixed`, forwards `$parameters`, and exposes a clearly named count. +- Keep the uncached-facade assertion: it must prove two container resolutions. +- Add or retain coverage that `setFacadeApplication(null)` is supported. + +All other inspected facade setup callers pass a concrete Hypervel container, an Application contract implementation, or `null` and require no compatibility layer. + +### 4. Migrate tests without hiding lifecycle choices + +Generate the candidate list with broad `grep` searches across all `tests/`, then inspect it one file at a time. After changing each test file, immediately run that file before moving to the next. + +For tests where bracket syntax is only setup: + +- Replace existing object and scalar registrations with `instance()`. This applies to config repositories, environment strings, cache doubles, storage paths, boolean provider flags, and similar fixed values. +- Replace closure registrations with `bind()`. +- Replace reads with `make()` and existence checks with `bound()`. +- Preserve config fallbacks and guards using the same typed-getter rule as source. +- Add `: void` to every test method whose body is changed, as required by the repository's test typing rules. +- Do not touch a value merely because its local variable is named `$app` or `$container`. For example, `tests/Integration/Http/RequestBindingTest.php` obtains a plain array from `config()->array('app')`; its `unset($app['url'])` remains unchanged. The reflected coordinator registry arrays in `tests/Coordinator/TimerTest.php` also remain arrays. +- Keep the local `$hypervel = []` Composer-metadata array in `tests/Testing/PHPUnit/TestStateRegistrarsTest.php`; it is distinct from the cloned application named `$hypervel` in Testbench `UsesVendor`. +- Convert the two cloned-application reads in `tests/Testbench/Foundation/Bootstrap/CreateVendorSymlinkTest.php` from `$application['TESTBENCH_VENDOR_SYMLINK']` to `make()`. They are real container reads, not Composer metadata arrays. + +Fixed-value assignment sites that need an explicit `instance()` audit include: + +- `tests/Support/SupportCapsuleManagerTraitTest.php` +- `tests/Integration/Horizon/Feature/MonitorSupervisorMemoryTest.php` +- `tests/Integration/Horizon/Feature/MonitorMasterSupervisorMemoryTest.php` +- `tests/Integration/Foundation/FoundationServiceProvidersTest.php` +- `tests/Integration/Encryption/KeyGenerateCommandTest.php` +- `tests/Telescope/FeatureTestCase.php` +- `tests/Cache/ClearCommandTest.php` +- `tests/Log/LogManagerTest.php` +- `tests/Foundation/FoundationHelpersTest.php` +- `tests/Foundation/FoundationDevCommandsTest.php` +- `tests/Foundation/Testing/DatabaseTruncationTest.php` +- `tests/Testbench/Fixtures/Providers/ParentServiceProvider.php` +- `tests/Testbench/Fixtures/Providers/ChildServiceProvider.php` + +Convert the four real magic config accesses in `tests/Support/SupportMaintenanceModeTest.php` to an explicitly resolved config repository. Do not change declared test properties such as `bootstrapFile`, `frameworkBootstrapCount`, or `waiterEntered`. + +The two queue payload fixtures, `tests/Integration/Queue/CustomPayloadTest.php` and `tests/Testbench/TestbenchTest.php`, should register the generated one-time password with `instance()` and clear it with `forgetInstance()`. Their purpose is to expose a stale static payload callback closing over a previous Application after its one-time entry has been cleared. The eager test-fixture value does not change that behavior. + +#### Container test changes + +The owner approved this exact list: + +| Current test | Change | Preserved coverage / marker | +|---|---|---| +| `ContainerTest::testArrayAccess` | Remove | Sole subject is the omitted interface. Leave `// REMOVED: Container ArrayAccess is intentionally unsupported; use named container methods.` at the matching upstream location. | +| `ContainerTest::testUnsetRemoveBoundInstances` | Consolidate into `testForgetInstanceForgetsInstance` | Add `bound()` assertions before and after `forgetInstance()`. Leave a `REMOVED:` marker at the upstream method location naming the destination coverage. | +| `ContainerTest::testBoundInstanceAndAliasCheckViaArrayAccess` | Keep under a named-method-oriented name | Replace `isset` with `bound()` for the instance and alias. Record the upstream-name mapping in the plan only; no removal marker. | +| `ContainerTest::testOffsetUnsetClearsScopedInstance` | Remove | Hypervel-original duplicate of existing `testForgetInstanceForgetsScopedInstance`; no upstream marker. | +| `ContainerTest::testOffsetUnsetClearsScopedLifecycleMarker` | Remove | Hypervel-original assertion for intentionally removed destructive unset behavior. `forgetInstance()` correctly preserves scoped lifecycle; an explicit non-scoped `bind()` changes lifecycle. No upstream marker. | +| `ContainerTest::testContainerCanDynamicallySetService` | Remove | Sole subject is offset existence/set/get. Leave the same concise ArrayAccess `REMOVED:` marker at this separate upstream location. | + +This produces three `REMOVED:` marker comments across four accounted upstream methods. The renamed bound/alias test remains executable but will require manual matching if its upstream-named counterpart changes. + +In `tests/Container/ContainerExtendTest.php`, convert offset-assignment setup to explicit transient `bind()` closures. Keep the current unset/extender test as a `forgetExtenders()` test and remove only the obsolete unset step. + +### 5. Document the intentional difference + +#### Package README + +Update `src/container/README.md` in the required README order: + +- Keep the header and badge. +- Add `Documentation: https://hypervel.org/docs/container` because the package has a meaningful public documentation page. +- Add `Differences From Laravel` explaining that Hypervel omits container ArrayAccess and dynamic service properties, and directs users to `make()` / `get()`, `bound()` / `has()`, `bind()`, `instance()`, and `forgetInstance()` for temporary overrides. State that arbitrary binding removal is not exposed because registrations are worker-global boot-time state. +- Add `Ported from: https://github.com/laravel/framework/tree/13.x/src/Illuminate/Container` after the difference section, matching the component-tree form used by Laravel-derived package READMEs. + +Do not describe ArrayAccess as deprecated or claim Laravel discourages it. State the verified current facts: Laravel retains the concrete API, while its contract and current documentation use named methods. + +#### Porting guide + +Update `src/docs/porting-from-laravel.md` concisely at `Container Lifecycles`, where it currently says Hypervel's container has Laravel's public shape: + +- State that Hypervel intentionally supports named container methods but not Laravel's ArrayAccess or dynamic service properties. +- Give compact porting mappings for read, existence, closure registration, fixed-instance registration, and temporary-instance cleanup. +- Keep the lifecycle table and worker-lifetime explanation as the authoritative lifecycle guidance. +- Do not add internal implementation detail, repository migration counts, edge-case history, or repeated rationale. + +#### Main container guide + +Update the introductory Laravel-comparison sentence in `src/docs/container.md`. It currently says the container's bindings and resolution helpers all behave like Laravel's, which becomes too broad after this public API removal. Keep the useful lifecycle comparison, but say that Hypervel follows Laravel's named binding and resolution APIs while documenting intentional public API differences in the porting guide. Do not duplicate the mappings or rationale here. No `src/docs` container example currently uses the removed syntax. + +#### Release overview + +Broaden the single intentional-differences clause in `src/docs/releases.md`'s `Laravel-Style Package Ports` section so it also says Hypervel may omit Laravel public APIs whose semantics do not suit Hypervel. Keep this at one high-level clause; do not add an API-specific subsection. + +Do not add an `src/docs/upgrade.md` entry. That guide is for Hypervel 0.3-to-0.4 applications, and the Hyperf container used by 0.3 did not implement ArrayAccess or the removed offset methods. Keep the separate `porting-from-laravel.md` entry for Laravel developers. Also leave `porting-from-laravel.md`'s statement about supported public binding methods unchanged; `bind()`, `singleton()`, `scoped()`, and provider `bindings` / `singletons` properties remain supported. + +#### Protected agent guide + +The owner approved and applied a deliberately minimal `AGENTS.md` update after peer signoff. It changes four conceptual locations so the guide never instructs future ports to use a removed API: + +1. `Container`: say Hypervel keeps Laravel's named API surface and intentionally omits array and dynamic service access. +2. `Porting Packages > Policy`: require ported container array and dynamic-property access to use named methods. +3. `Porting Laravel Tests > Approved unsupported features`: add container ArrayAccess and dynamic service properties to the exhaustive list so future tests whose sole subject is those APIs are removed with the required markers. +4. `Development Conventions`: clarify in the existing typed-config rule that code must not supply a second fallback when framework or package config defines the key, so missing or misspelled keys fail loudly. + +The quick checklist now points to the exhaustive list instead of duplicating it. No method mapping, compatibility rationale, or arbitrary binding-removal guidance was added; those unneeded instructions would increase context and the risk of misinterpretation without addressing an observed agent failure. + +### 6. Keep verified generic behavior unchanged + +- `src/facade-documenter/facade.php::fulfillsBuiltinInterface()` remains generic. Its ArrayAccess filter still applies to real ArrayAccess facade targets and simply stops matching the App container; no generated App offset methods exist. +- `src/testbench/src/Bootstrapper.php` keeps `static::$configuration?->offsetExists('hypervel')` and `static::$configuration['hypervel']`. That value implements `Hypervel\Testbench\Contracts\Config`, which intentionally extends ArrayAccess; it is not the application container. +- Genuine ArrayAccess APIs elsewhere in Hypervel—collections, config repositories, HTTP responses, requests, data objects, views, cache tag wrappers, and similar map-like objects—remain supported and documented. +- Preserve `_archive` unchanged. It is a parked historical snapshot scheduled for deletion after 0.4, not active framework source, and is excluded from migration and search gates. +- Private package and application source had no real container array or dynamic-property callers after excluding vendor, generated, and reference-copy directories. Re-run that verification when implementing, but do not edit third-party or generated trees. + +## Testing and verification + +### Per-file cadence + +- After each changed test file: `./vendor/bin/phpunit --no-progress path/to/Test.php`. +- Run `tests/Container/ContainerTest.php` immediately after its source/test edits, then `tests/Container/ContainerExtendTest.php`. +- Run `tests/Support/SupportFacadeTest.php` after the facade boundary and test-double conversion. +- Run `tests/Foundation/Testing/Concerns/MakesHttpRequestsTest.php` after the middleware cleanup fix. +- Run `tests/Console/ArtisanCommandTest.php` after `PendingCommand` changes even if the test file itself does not change. +- Run `tests/Foundation/FoundationApplicationTest.php` and `tests/Foundation/ApplicationRunningInConsoleTest.php` after converting `Application` self-access and extending the stored-environment assertion. +- Run `tests/Console/ConfiguresPromptsTest.php`, `tests/Console/GeneratorCommandTest.php`, and each affected package's matching command tests after the console-command conversions. +- Run `tests/Testbench/Attributes/UsesVendorTest.php` after converting the cloned application read. +- Run `tests/Concurrency/ConcurrencyTest.php` immediately after the approved manager and regression-test changes. +- Run the queue custom-payload and Testbench files immediately after each fixture edit. +- Run `composer test:testbench` after the Testbench source/test slice. + +### Search gates + +Use broad Bash `grep` searches across the whole `src/` and `tests/` trees: + +- Confirm the Hypervel container contract and concrete class no longer import, extend, or implement `ArrayAccess` and define no `offset*`, `__get`, or `__set` methods. +- Before implementation and again as the closing backstop, rank every bracket receiver without assuming container variable names: + + ```bash + grep -rhoE -e '(\$this->[a-zA-Z_][a-zA-Z0-9_]*|static::\$[a-zA-Z_][a-zA-Z0-9_]*|\$[a-zA-Z_][a-zA-Z0-9_]*)\[' src tests --include='*.php' \ + | sed -E 's/\[$//' | sort | uniq -c | sort -rn + ``` + + Inspect the complete ranked output for any receiver that is or may be a container. This discovery step is mandatory; the original fixed-name search missed both `$this->hypervel` and container self-access. +- Search bracket access through the known container identifier family: `$this->app`, `$app`, `static::$app`, `$this->application`, `$application`, `$this->container`, `$container`, `$this->hypervel`, and `$hypervel`. Also search bare `$this[...]` across all source and tests; the current twelve hits are the ten `Application` callers plus the two container magic-accessor implementations, so none should remain after this change. Inspect every other remainder; only genuine array or non-container ArrayAccess values may remain. In source, the known ordinary-array files are the Reverb config provider, ServerManager, CoordinatorManager, AspectManager, and `PackageManifest`; Testbench `Bootstrapper::$configuration` is the known non-container ArrayAccess value. +- Search direct `offsetExists/Get/Set/Unset` calls on app/container variables; none may remain. +- Run a shape-based magic-property search across source and tests, including `app`, `application`, `container`, and `hypervel` identifiers: + + ```bash + grep -RInP --include='*.php' '(?:->(?:app|application|container|hypervel)|\$(?:app|application|container|hypervel))->[a-z_][A-Za-z0-9_]*(?![A-Za-z0-9_]|\s*\()' src tests + ``` + + Inspect every hit. No container service property may remain; declared fixture or test-double properties such as `bootstrapFile`, `frameworkBootstrapCount`, `middlewarePriority`, `waiterEntered`, and parallel-runner tracking fields remain valid. +- Search active `src/docs`, package READMEs, and the porting guide for stale claims or examples that say container array/dynamic access is supported; exclude `_archive` and historical plan files. +- Repeat the same checks across `apps/`, `packages/hypervel/`, and `packages/hypervel-dev/`, excluding dependency, generated, temporary-reference, and storage trees; any real caller must be converted under the same rules. + +### Final checks + +After all targeted tests are green, run `composer fix` once from the worktree root. It runs formatting, both PHPStan configurations, the full parallel suite, Testbench package-mode tests, and the dogfood package tests. + +If `composer fix` fails: + +1. Investigate the exact failure and apply only verified fixes. +2. Run the corrected targeted test/check. +3. Inspect the current `fix` script and run the failed entry plus every remaining entry in order. Do not repeat an earlier passing entry unless the fix can affect it. +4. Re-run the search gates after formatter or review fixes. + +## Implementation order + +1. Remove ArrayAccess from the contract and concrete container, including magic accessors and the required source marker. +2. Convert production consumers one file at a time, including middleware/PendingCommand lifecycle fixes and facade typing fallout. +3. Convert tests one file at a time, running each file immediately and leaving verified ordinary arrays unchanged. +4. Update the container README, main container guide, porting guide, and release overview with targeted edits. +5. Run focused suites, search gates, `composer test:testbench` for the Testbench slice, and one full `composer fix` checkpoint. +6. Re-read this plan, inspect the final diff file by file for stale compatibility code or documentation, and request code review before handoff. + +## Primary references + +- Laravel 13 container documentation: +- Laravel 13 concrete container: +- Laravel 13 container contract: +- Laravel discussion rejecting ArrayAccess on the contract: +- PSR-11 specification and rationale: and +- Current PHP-DI, Symfony DI, and League Container concrete sources, checked only to establish that method-only containers are normal modern PHP practice. + +Historical wording must stay narrow: ArrayAccess was present in the first tagged Illuminate container, while Laravel 3.2 used its own static IoC class without it. Do not call the API Pimple inheritance. diff --git a/src/cache/src/Console/ClearCommand.php b/src/cache/src/Console/ClearCommand.php index c36033305..19948814e 100644 --- a/src/cache/src/Console/ClearCommand.php +++ b/src/cache/src/Console/ClearCommand.php @@ -45,7 +45,9 @@ public function handle(): int return $this->clearLocks(); } - $this->hypervel['events']->dispatch( + $events = $this->hypervel->make('events'); + + $events->dispatch( 'cache:clearing', [$this->argument('store'), $this->tags()] ); @@ -61,7 +63,7 @@ public function handle(): int return self::FAILURE; } - $this->hypervel['events']->dispatch( + $events->dispatch( 'cache:cleared', [$this->argument('store'), $this->tags()] ); diff --git a/src/concurrency/src/ConcurrencyManager.php b/src/concurrency/src/ConcurrencyManager.php index 69c74a798..73048752b 100644 --- a/src/concurrency/src/ConcurrencyManager.php +++ b/src/concurrency/src/ConcurrencyManager.php @@ -60,9 +60,7 @@ public function createSyncDriver(): SyncDriver */ public function getDefaultInstance(): string { - return $this->app['config']['concurrency.default'] - ?? $this->app['config']['concurrency.driver'] - ?? 'coroutine'; + return $this->config->string('concurrency.default'); } /** @@ -72,8 +70,7 @@ public function getDefaultInstance(): string */ public function setDefaultInstance(string $name): void { - $this->app['config']['concurrency.default'] = $name; - $this->app['config']['concurrency.driver'] = $name; + $this->config->set('concurrency.default', $name); } /** @@ -81,7 +78,7 @@ public function setDefaultInstance(string $name): void */ public function getInstanceConfig(string $name): array { - return $this->app['config']->get( + return $this->config->array( 'concurrency.driver.' . $name, ['driver' => $name], ); diff --git a/src/console/src/Concerns/ConfiguresPrompts.php b/src/console/src/Concerns/ConfiguresPrompts.php index 1784935b1..5d96d669a 100644 --- a/src/console/src/Concerns/ConfiguresPrompts.php +++ b/src/console/src/Concerns/ConfiguresPrompts.php @@ -219,7 +219,7 @@ protected function validatePrompt($value, $rules) */ protected function getPromptValidatorInstance($field, $value, $rules, array $messages = [], array $attributes = []) { - return $this->hypervel['validator']->make( + return $this->hypervel->make('validator')->make( [$field => $value], [$field => $rules], empty($messages) ? $this->validationMessages() : $messages, diff --git a/src/console/src/Concerns/CreatesMatchingTest.php b/src/console/src/Concerns/CreatesMatchingTest.php index 87daf6171..523bbafe5 100644 --- a/src/console/src/Concerns/CreatesMatchingTest.php +++ b/src/console/src/Concerns/CreatesMatchingTest.php @@ -34,7 +34,7 @@ protected function handleTestCreation(string $path): bool } return $this->call('make:test', [ - 'name' => (new Stringable($path))->after($this->hypervel['path'])->beforeLast('.php')->append('Test')->replace('\\', '/')->value(), + 'name' => (new Stringable($path))->after($this->hypervel->make('path'))->beforeLast('.php')->append('Test')->replace('\\', '/')->value(), '--pest' => $this->option('pest'), '--phpunit' => $this->option('phpunit'), '--force' => $this->hasOption('force') && $this->option('force'), diff --git a/src/container/README.md b/src/container/README.md index 387836c11..0e7a341c0 100644 --- a/src/container/README.md +++ b/src/container/README.md @@ -1,4 +1,12 @@ Container for Hypervel === -[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/hypervel/container) \ No newline at end of file +[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/hypervel/container) + +Documentation: https://hypervel.org/docs/container + +## Differences From Laravel + +Hypervel supports Laravel's named container APIs, but not container ArrayAccess or dynamic service properties. Use `make()` / `get()`, `bound()` / `has()`, `bind()`, and `instance()`. For temporary instance overrides, use `forgetInstance()` to restore the original binding. Hypervel does not expose arbitrary binding removal because registrations are worker-wide boot-time state. + +Ported from: https://github.com/laravel/framework/tree/13.x/src/Illuminate/Container diff --git a/src/container/src/Container.php b/src/container/src/Container.php index 2e7f38a6c..20a164633 100755 --- a/src/container/src/Container.php +++ b/src/container/src/Container.php @@ -4,7 +4,6 @@ namespace Hypervel\Container; -use ArrayAccess; use Closure; use Exception; use Hypervel\Container\Attributes\Bind; @@ -30,7 +29,7 @@ use Throwable; use TypeError; -class Container implements ArrayAccess, ContainerContract +class Container implements ContainerContract { use ReflectsClosures; @@ -711,9 +710,9 @@ public function extend(string $abstract, Closure $closure): void /** * Register an existing instance as shared in the container. * - * Tests only. Replaces a worker-lifetime shared instance; runtime use races - * across coroutines and changes the object returned to every subsequent - * resolver. + * Boot or tests only. Replaces a worker-lifetime shared instance; runtime + * use races across coroutines and changes the object returned to every + * subsequent resolver. * * @template TInstance of mixed * @@ -2379,62 +2378,6 @@ public static function flushState(): void static::$buildRecipes = []; } - /** - * Determine if a given offset exists. - * - * @param string $key - */ - public function offsetExists($key): bool - { - return $this->bound($key); - } - - /** - * Get the value at a given offset. - * - * @param string $key - */ - public function offsetGet($key): mixed - { - return $this->make($key); - } - - /** - * Set the value at a given offset. - * - * @param string $key - * @param mixed $value - */ - public function offsetSet($key, $value): void - { - $this->bind($key, $value instanceof Closure ? $value : fn () => $value); - } - - /** - * Unset the value at a given offset. - * - * @param string $key - */ - public function offsetUnset($key): void - { - unset($this->bindings[$key], $this->resolved[$key], $this->scopedInstances[$key]); - - $this->dropStaleInstances($key); - } - - /** - * Dynamically access container services. - */ - public function __get(string $key): mixed - { - return $this[$key]; - } - - /** - * Dynamically set container services. - */ - public function __set(string $key, mixed $value): void - { - $this[$key] = $value; - } + // Hypervel intentionally omits container array and dynamic property access. + // Use named methods so resolution and binding lifecycles remain explicit. } diff --git a/src/contracts/src/Container/Container.php b/src/contracts/src/Container/Container.php index 7a88157a5..07c88666f 100644 --- a/src/contracts/src/Container/Container.php +++ b/src/contracts/src/Container/Container.php @@ -4,13 +4,12 @@ namespace Hypervel\Contracts\Container; -use ArrayAccess; use Closure; use InvalidArgumentException; use LogicException; use Psr\Container\ContainerInterface; -interface Container extends ArrayAccess, ContainerInterface +interface Container extends ContainerInterface { /** * @template TClass of object diff --git a/src/database/src/Capsule/Manager.php b/src/database/src/Capsule/Manager.php index 916a42bbf..6b9eab9b0 100644 --- a/src/database/src/Capsule/Manager.php +++ b/src/database/src/Capsule/Manager.php @@ -59,7 +59,9 @@ public function __construct(?ContainerContract $container = null) */ protected function setupDefaultConfiguration(): void { - $this->container['config']['database.default'] = 'default'; + $configuration = $this->container->make('config'); + + $configuration['database.default'] = 'default'; } /** @@ -119,11 +121,12 @@ public function getConnection(?string $name = null): ConnectionInterface */ public function addConnection(array $config, string $name = 'default'): void { - $connections = $this->container['config']['database.connections']; + $configuration = $this->container->make('config'); + $connections = $configuration['database.connections'] ?? []; $connections[$name] = $config; - $this->container['config']['database.connections'] = $connections; + $configuration['database.connections'] = $connections; } /** @@ -158,7 +161,7 @@ public function getDatabaseManager(): DatabaseManager public function getEventDispatcher(): ?Dispatcher { if ($this->container->bound('events')) { - return $this->container['events']; + return $this->container->make('events'); } return null; diff --git a/src/database/src/Console/Migrations/MigrateCommand.php b/src/database/src/Console/Migrations/MigrateCommand.php index bc416473d..6d7476987 100644 --- a/src/database/src/Console/Migrations/MigrateCommand.php +++ b/src/database/src/Console/Migrations/MigrateCommand.php @@ -222,7 +222,7 @@ protected function createMissingSqliteDatabase(string $path): bool protected function createMissingMySqlOrPgsqlDatabase(Connection $connection): bool { $adminConfig = (new ConfigurationUrlParser)->parseConfiguration( - $this->hypervel['config']->get("database.connections.{$connection->getName()}") + $this->hypervel->make('config')->get("database.connections.{$connection->getName()}") ); if (($adminConfig['database'] ?? null) !== $connection->getDatabaseName()) { diff --git a/src/database/src/Console/Migrations/RefreshCommand.php b/src/database/src/Console/Migrations/RefreshCommand.php index 7d5501923..3ef45a9b2 100644 --- a/src/database/src/Console/Migrations/RefreshCommand.php +++ b/src/database/src/Console/Migrations/RefreshCommand.php @@ -67,7 +67,7 @@ public function handle(): int ])); if ($this->hypervel->bound(Dispatcher::class)) { - $this->hypervel[Dispatcher::class]->dispatch( + $this->hypervel->make(Dispatcher::class)->dispatch( new DatabaseRefreshed($database, $this->needsSeeding()) ); } diff --git a/src/database/src/Console/WipeCommand.php b/src/database/src/Console/WipeCommand.php index 61fb55923..cb3b9bf61 100644 --- a/src/database/src/Console/WipeCommand.php +++ b/src/database/src/Console/WipeCommand.php @@ -67,7 +67,7 @@ public function handle(): int */ protected function dropAllTables(?string $database): void { - $this->hypervel['db']->connection($database) + $this->hypervel->make('db')->connection($database) ->getSchemaBuilder() ->dropAllTables(); } @@ -77,7 +77,7 @@ protected function dropAllTables(?string $database): void */ protected function dropAllViews(?string $database): void { - $this->hypervel['db']->connection($database) + $this->hypervel->make('db')->connection($database) ->getSchemaBuilder() ->dropAllViews(); } @@ -87,7 +87,7 @@ protected function dropAllViews(?string $database): void */ protected function dropAllTypes(?string $database): void { - $this->hypervel['db']->connection($database) + $this->hypervel->make('db')->connection($database) ->getSchemaBuilder() ->dropAllTypes(); } @@ -103,7 +103,7 @@ protected function dropAllTypes(?string $database): void */ protected function flushDatabaseConnection(?string $database): void { - $this->hypervel['db']->purge($database); + $this->hypervel->make('db')->purge($database); } /** diff --git a/src/database/src/DatabaseServiceProvider.php b/src/database/src/DatabaseServiceProvider.php index 8427f221e..8d2acd98b 100644 --- a/src/database/src/DatabaseServiceProvider.php +++ b/src/database/src/DatabaseServiceProvider.php @@ -57,28 +57,28 @@ public function register(): void $this->app->singleton('db.resolver', fn ($app) => $app->make(ConnectionResolver::class)); $this->app->singleton('migration.repository', function ($app) { - $migrations = $app['config']['database.migrations']; + $migrations = $app->make('config')->get('database.migrations'); $table = is_array($migrations) ? ($migrations['table'] ?? 'migrations') : $migrations; return new DatabaseMigrationRepository( - $app['db'], + $app->make('db'), $table, ); }); $this->app->singleton('migrator', function ($app) { return new Migrator( - $app['migration.repository'], - $app['db'], - $app['files'], + $app->make('migration.repository'), + $app->make('db'), + $app->make('files'), ); }); $this->app->singleton('migration.creator', function ($app) { - return new MigrationCreator($app['files'], $app->basePath('stubs')); + return new MigrationCreator($app->make('files'), $app->basePath('stubs')); }); $this->commands([ @@ -136,11 +136,11 @@ protected function registerConnectionServices(): void }); $this->app->singleton('db', function ($app) { - return new DatabaseManager($app, $app['db.factory']); + return new DatabaseManager($app, $app->make('db.factory')); }); $this->app->bind('db.connection', function ($app) { - return $app['db']->connection(); + return $app->make('db')->connection(); }); $this->app->singleton('db.schema', function () { @@ -174,7 +174,7 @@ protected function registerFakerGenerator(): void } $this->app->scoped(FakerGenerator::class, function ($app, $parameters) { - $locale = $parameters['locale'] ?? $app['config']->get('app.faker_locale', 'en_US'); + $locale = $parameters['locale'] ?? $app->make('config')->get('app.faker_locale', 'en_US'); return FakerFactory::create($locale); }); diff --git a/src/database/src/Migrations/Migrator.php b/src/database/src/Migrations/Migrator.php index 740d4b117..5ad919468 100755 --- a/src/database/src/Migrations/Migrator.php +++ b/src/database/src/Migrations/Migrator.php @@ -818,7 +818,7 @@ public function fireMigrationEvent(MigrationEventContract $event): void $container = Container::getInstance(); if ($container->bound(Dispatcher::class)) { - $container[Dispatcher::class]->dispatch($event); + $container->make(Dispatcher::class)->dispatch($event); } } diff --git a/src/docs/container.md b/src/docs/container.md index 53dc4765e..ff1aba0b1 100644 --- a/src/docs/container.md +++ b/src/docs/container.md @@ -63,7 +63,7 @@ class PodcastController extends Controller In this example, the `PodcastController` needs to retrieve podcasts from a data source such as Apple Music. So, we will **inject** a service that is able to retrieve podcasts. Since the service is injected, we are able to easily "mock", or create a dummy implementation of the `AppleMusic` service when testing our application. -Hypervel's container is similar to Laravel's but resolves under a long-running Swoole worker. The bindings, attributes, and resolution helpers all behave like Laravel's, but instance caching is more aggressive and the per-request lifecycle is keyed to a coroutine rather than a fresh PHP process. See [Resolution Lifecycles](#resolution-lifecycles) for the behaviors that differ. +Hypervel's container follows Laravel's named binding and resolution APIs while running inside a long-lived Swoole worker. Intentional public API differences are covered in the [porting guide](/docs/{{version}}/porting-from-laravel#container-lifecycles). Instance caching is more aggressive, and the per-request lifecycle is keyed to a coroutine rather than a fresh PHP process. See [Resolution Lifecycles](#resolution-lifecycles) for the lifecycle differences. ### Zero Configuration Resolution diff --git a/src/docs/porting-from-laravel.md b/src/docs/porting-from-laravel.md index fff0b5c55..55b50364b 100644 --- a/src/docs/porting-from-laravel.md +++ b/src/docs/porting-from-laravel.md @@ -383,7 +383,19 @@ If a public method mutates static or singleton-held state, make sure that state ### Container Lifecycles -Hypervel's container has the same public shape as Laravel's container, but its lifecycle is adapted for Swoole: +Hypervel follows Laravel's named container APIs, but intentionally does not support container ArrayAccess or dynamic service properties. Convert those calls while porting: + +| Laravel | Hypervel | +|---|---| +| `$app['events']` or `$app->events` | `$app->make('events')` | +| `isset($app['events'])` | `$app->bound('events')` | +| `$app['service'] = fn ($app) => ...` or `$app->service = fn ($app) => ...` | `$app->bind('service', fn ($app) => ...)` | +| `$app['service'] = $service` or `$app->service = $service` | `$app->instance('service', $service)` | +| Remove a temporary instance override | `$app->forgetInstance('service')` | + +Use `get()` and `has()` instead when working through the PSR-11 container interface. Hypervel does not expose arbitrary binding removal; `forgetInstance()` clears a temporary instance so the original binding can resolve again. + +Container lifecycles are adapted for Swoole: | Need | Method | |---|---| diff --git a/src/docs/releases.md b/src/docs/releases.md index e2649a699..041aa214f 100644 --- a/src/docs/releases.md +++ b/src/docs/releases.md @@ -65,7 +65,7 @@ Hypervel runs on Swoole using long-lived workers and coroutines. This architectu Many Hypervel 0.4 packages are fresh ports of Laravel packages. These ports aim to provide an API that is almost identical to Laravel where the feature makes sense for Hypervel. -Some differences are intentional. Hypervel uses `Hypervel\` namespaces, adapts internals for coroutine safety, adds Swoole-specific performance optimizations, and removes drivers or integrations that Hypervel does not support. +Some differences are intentional. Hypervel uses `Hypervel\` namespaces, adapts internals for coroutine safety, adds Swoole-specific performance optimizations, may omit Laravel public APIs whose semantics do not suit Hypervel, and removes drivers or integrations that Hypervel does not support. ### Immutable Dates diff --git a/src/filesystem/src/FilesystemManager.php b/src/filesystem/src/FilesystemManager.php index 916907078..17de8a950 100644 --- a/src/filesystem/src/FilesystemManager.php +++ b/src/filesystem/src/FilesystemManager.php @@ -332,7 +332,7 @@ public function createLocalDriver(array $config, string $name = 'local'): Filesy $name )->shouldServeSignedUrls( $config['serve'] ?? false, - fn () => $this->app['url'], + fn () => $this->app->make('url'), ); } diff --git a/src/foundation/src/Application.php b/src/foundation/src/Application.php index 922e2be6f..89eff1ec5 100644 --- a/src/foundation/src/Application.php +++ b/src/foundation/src/Application.php @@ -308,11 +308,11 @@ public function bootstrapWith(array $bootstrappers): void $this->hasBeenBootstrapped = true; foreach ($bootstrappers as $bootstrapper) { - $this['events']->dispatch('bootstrapping: ' . $bootstrapper, [$this]); + $this->make('events')->dispatch('bootstrapping: ' . $bootstrapper, [$this]); $this->make($bootstrapper)->bootstrap($this); - $this['events']->dispatch('bootstrapped: ' . $bootstrapper, [$this]); + $this->make('events')->dispatch('bootstrapped: ' . $bootstrapper, [$this]); } } @@ -321,7 +321,7 @@ public function bootstrapWith(array $bootstrappers): void */ public function beforeBootstrapping(string $bootstrapper, Closure $callback): void { - $this['events']->listen('bootstrapping: ' . $bootstrapper, $callback); + $this->make('events')->listen('bootstrapping: ' . $bootstrapper, $callback); } /** @@ -329,7 +329,7 @@ public function beforeBootstrapping(string $bootstrapper, Closure $callback): vo */ public function afterBootstrapping(string $bootstrapper, Closure $callback): void { - $this['events']->listen('bootstrapped: ' . $bootstrapper, $callback); + $this->make('events')->listen('bootstrapped: ' . $bootstrapper, $callback); } /** @@ -758,10 +758,10 @@ public function environment(array|string ...$environments): bool|string if (count($environments) > 0) { $patterns = is_array($environments[0]) ? $environments[0] : $environments; - return Str::is($patterns, $this['env']); + return Str::is($patterns, $this->make('env')); } - return $this['env']; + return $this->make('env'); } /** @@ -769,7 +769,7 @@ public function environment(array|string ...$environments): bool|string */ public function isLocal(): bool { - return $this['env'] === 'local'; + return $this->make('env') === 'local'; } /** @@ -777,7 +777,7 @@ public function isLocal(): bool */ public function isProduction(): bool { - return $this['env'] === 'production'; + return $this->make('env') === 'production'; } /** @@ -789,7 +789,7 @@ public function detectEnvironment(Closure $callback): string ? $_SERVER['argv'] : null; - return $this['env'] = (new EnvironmentDetector)->detect($callback, $args); + return $this->instance('env', (new EnvironmentDetector)->detect($callback, $args)); } /** @@ -841,7 +841,7 @@ public function setRunningInConsole(bool $runningInConsole): void */ public function runningUnitTests(): bool { - return $this->bound('env') && $this['env'] === 'testing'; + return $this->bound('env') && $this->make('env') === 'testing'; } /** diff --git a/src/foundation/src/Bootstrap/HandleExceptions.php b/src/foundation/src/Bootstrap/HandleExceptions.php index 3c14fd27b..d1185dbe1 100644 --- a/src/foundation/src/Bootstrap/HandleExceptions.php +++ b/src/foundation/src/Bootstrap/HandleExceptions.php @@ -86,7 +86,7 @@ public function handleDeprecationError(string $message, string $file, int $line, $this->ensureDeprecationLoggerIsConfigured(); - $options = static::$app['config']->get('logging.deprecations') ?? []; + $options = static::$app->make('config')->get('logging.deprecations') ?? []; with($logger->channel('deprecations'), function ($log) use ($message, $file, $line, $level, $options) { if ($options['trace'] ?? false) { @@ -118,7 +118,7 @@ protected function shouldIgnoreDeprecationErrors(): bool */ protected function ensureDeprecationLoggerIsConfigured(): void { - $config = static::$app['config']; + $config = static::$app->make('config'); if ($config->get('logging.channels.deprecations')) { return; @@ -140,7 +140,7 @@ protected function ensureDeprecationLoggerIsConfigured(): void */ protected function ensureNullLogDriverIsConfigured(): void { - $config = static::$app['config']; + $config = static::$app->make('config'); if ($config->get('logging.channels.null')) { return; diff --git a/src/foundation/src/Console/ConfigCacheCommand.php b/src/foundation/src/Console/ConfigCacheCommand.php index c0ea22216..3bdaca348 100644 --- a/src/foundation/src/Console/ConfigCacheCommand.php +++ b/src/foundation/src/Console/ConfigCacheCommand.php @@ -194,7 +194,7 @@ protected function getFreshConfigurationCacheContentsFromSubprocess(): string */ protected function buildFreshConfigurationCacheContents(): string { - $config = $this->hypervel['config']->all(); + $config = $this->hypervel->make('config')->all(); $contents = 'components->info(sprintf( 'The application environment is [%s].', - $this->hypervel['env'], + $this->hypervel->make('env'), )); } } diff --git a/src/foundation/src/Console/Kernel.php b/src/foundation/src/Console/Kernel.php index 08732b5c3..033743dd8 100644 --- a/src/foundation/src/Console/Kernel.php +++ b/src/foundation/src/Console/Kernel.php @@ -280,7 +280,7 @@ public function resolveConsoleSchedule(): Schedule */ protected function scheduleTimezone(): ?string { - $config = $this->app['config']; + $config = $this->app->make('config'); return $config->get('app.schedule_timezone', $config->get('app.timezone')); } @@ -290,7 +290,7 @@ protected function scheduleTimezone(): ?string */ protected function scheduleCache(): ?string { - return $this->app['config']->get('cache.schedule_store', Env::get('SCHEDULE_CACHE_DRIVER', function () { + return $this->app->make('config')->get('cache.schedule_store', Env::get('SCHEDULE_CACHE_DRIVER', function () { return Env::get('SCHEDULE_CACHE_STORE'); })); } diff --git a/src/foundation/src/Console/RouteCacheCommand.php b/src/foundation/src/Console/RouteCacheCommand.php index 2f044e2e6..b4a1900ff 100644 --- a/src/foundation/src/Console/RouteCacheCommand.php +++ b/src/foundation/src/Console/RouteCacheCommand.php @@ -50,7 +50,7 @@ public function handle(): int // The app booted against a guaranteed-unused cache path, so the router // holds a live RouteCollection loaded from source route definitions. if (is_string($dumpPath = $this->option('dump-to')) && $dumpPath !== '') { - $routes = $this->hypervel['router']->getRoutes(); + $routes = $this->hypervel->make('router')->getRoutes(); if (! $routes instanceof RouteCollection) { throw new LogicException('Fresh route dump expected a live RouteCollection.'); diff --git a/src/foundation/src/Console/RouteListCommand.php b/src/foundation/src/Console/RouteListCommand.php index 75ba5a827..3597fe26f 100644 --- a/src/foundation/src/Console/RouteListCommand.php +++ b/src/foundation/src/Console/RouteListCommand.php @@ -413,7 +413,7 @@ protected function formatActionForCli(array $route): ?string $name = $name ? "{$name} " : null; - $rootControllerNamespace = $this->hypervel[UrlGenerator::class]->getRootControllerNamespace() + $rootControllerNamespace = $this->hypervel->make(UrlGenerator::class)->getRootControllerNamespace() ?? ($this->hypervel->getNamespace() . 'Http\Controllers'); if (str_starts_with($action, $rootControllerNamespace)) { diff --git a/src/foundation/src/Http/Kernel.php b/src/foundation/src/Http/Kernel.php index 620f82a38..d3aba0dd3 100644 --- a/src/foundation/src/Http/Kernel.php +++ b/src/foundation/src/Http/Kernel.php @@ -133,7 +133,7 @@ public function handle(Request $request): Response $request->enableHttpMethodParameterOverride(); $response = $this->sendRequestThroughRouter($request); - $events = $this->app['events']; + $events = $this->app->make('events'); if ($events->hasListeners(RequestHandled::class)) { $events->dispatch( @@ -209,7 +209,7 @@ protected function dispatchToRouter(): Closure public function terminate(Request $request, Response $response): void { $exception = null; - $events = $this->app['events']; + $events = $this->app->make('events'); try { if ($events->hasListeners(Terminating::class)) { diff --git a/src/foundation/src/Providers/FoundationServiceProvider.php b/src/foundation/src/Providers/FoundationServiceProvider.php index ce60cd65f..b54c912c3 100644 --- a/src/foundation/src/Providers/FoundationServiceProvider.php +++ b/src/foundation/src/Providers/FoundationServiceProvider.php @@ -148,7 +148,7 @@ public function boot(): void public function register(): void { $this->app->singleton('composer', fn ($app) => new Composer( - $app['files'], + $app->make('files'), $app->basePath() )); @@ -275,13 +275,14 @@ protected function registerConsoleSchedule(): void protected function registerDeferHandler(): void { $this->app->scoped(DeferredCallbackCollection::class); + $events = $this->app->make('events'); - $this->app['events']->listen(function (CommandFinished $event) { + $events->listen(function (CommandFinished $event) { $this->app->make(DeferredCallbackCollection::class) ->invokeWhen(fn (DeferredCallback $callback) => $this->app->runningInConsole() && ($event->exitCode === 0 || $callback->always)); }); - $this->app['events']->listen(function (JobAttempted $event) { + $events->listen(function (JobAttempted $event) { if (in_array($event->connectionName, ['sync', 'deferred'], true)) { return; } diff --git a/src/foundation/src/Support/Providers/RouteServiceProvider.php b/src/foundation/src/Support/Providers/RouteServiceProvider.php index 5fc28a034..efaff67d6 100644 --- a/src/foundation/src/Support/Providers/RouteServiceProvider.php +++ b/src/foundation/src/Support/Providers/RouteServiceProvider.php @@ -51,8 +51,9 @@ public function register(): void $this->loadRoutes(); $this->app->booted(function () { - $this->app['router']->getRoutes()->refreshNameLookups(); - $this->app['router']->getRoutes()->refreshActionLookups(); + $routes = $this->app->make('router')->getRoutes(); + $routes->refreshNameLookups(); + $routes->refreshActionLookups(); }); } }); @@ -114,7 +115,7 @@ public static function flushState(): void protected function setRootControllerNamespace(): void { if (! is_null($this->namespace)) { - $this->app[UrlGenerator::class]->setRootControllerNamespace($this->namespace); + $this->app->make(UrlGenerator::class)->setRootControllerNamespace($this->namespace); } } diff --git a/src/foundation/src/Testing/Concerns/InteractsWithAuthentication.php b/src/foundation/src/Testing/Concerns/InteractsWithAuthentication.php index 8f2f05e30..97fd24cfe 100644 --- a/src/foundation/src/Testing/Concerns/InteractsWithAuthentication.php +++ b/src/foundation/src/Testing/Concerns/InteractsWithAuthentication.php @@ -21,9 +21,11 @@ public function actingAs(UserContract $user, ?string $guard = null): static */ public function actingAsGuest(?string $guard = null): static { - $this->app['auth']->guard($guard)->forgetUser(); + $auth = $this->app->make('auth'); - $this->app['auth']->shouldUse($guard); + $auth->guard($guard)->forgetUser(); + + $auth->shouldUse($guard); return $this; } @@ -37,9 +39,11 @@ public function be(UserContract $user, ?string $guard = null): static $user->wasRecentlyCreated = false; } - $this->app['auth']->guard($guard)->setUser($user); + $auth = $this->app->make('auth'); + + $auth->guard($guard)->setUser($user); - $this->app['auth']->shouldUse($guard); + $auth->shouldUse($guard); return $this; } diff --git a/src/foundation/src/Testing/Concerns/InteractsWithSession.php b/src/foundation/src/Testing/Concerns/InteractsWithSession.php index 9c7089409..6f15d4f18 100644 --- a/src/foundation/src/Testing/Concerns/InteractsWithSession.php +++ b/src/foundation/src/Testing/Concerns/InteractsWithSession.php @@ -22,9 +22,10 @@ public function withSession(array $data): static public function session(array $data): static { $this->startSession(); + $session = $this->app->make('session'); foreach ($data as $key => $value) { - $this->app['session']->put($key, $value); + $session->put($key, $value); } return $this; @@ -35,8 +36,10 @@ public function session(array $data): static */ protected function startSession(): static { - if (! $this->app['session']->isStarted()) { - $this->app['session']->start(); + $session = $this->app->make('session'); + + if (! $session->isStarted()) { + $session->start(); } return $this; @@ -49,7 +52,7 @@ public function flushSession(): static { $this->startSession(); - $this->app['session']->flush(); + $this->app->make('session')->flush(); return $this; } diff --git a/src/foundation/src/Testing/Concerns/MakesHttpRequests.php b/src/foundation/src/Testing/Concerns/MakesHttpRequests.php index d4b454cb6..dca1c7681 100644 --- a/src/foundation/src/Testing/Concerns/MakesHttpRequests.php +++ b/src/foundation/src/Testing/Concerns/MakesHttpRequests.php @@ -181,13 +181,13 @@ public function withoutMiddleware($middleware = null): static public function withMiddleware($middleware = null): static { if (is_null($middleware)) { - unset($this->app['middleware.disable']); + $this->app->forgetInstance('middleware.disable'); return $this; } foreach ((array) $middleware as $abstract) { - unset($this->app[$abstract]); + $this->app->forgetInstance($abstract); } return $this; @@ -268,7 +268,7 @@ public function disableCookieEncryption(): static */ public function from(string $url): static { - $this->app['session']->setPreviousUrl($url); + $this->app->make('session')->setPreviousUrl($url); return $this->withHeader('referer', $url); } @@ -278,7 +278,7 @@ public function from(string $url): static */ public function fromRoute(BackedEnum|string $name, mixed $parameters = []): static { - return $this->from($this->app['url']->route($name, $parameters)); + return $this->from($this->app->make('url')->route($name, $parameters)); } /** diff --git a/src/foundation/src/Testing/DatabaseTruncation.php b/src/foundation/src/Testing/DatabaseTruncation.php index 85c9ea02f..8e9a93bdb 100644 --- a/src/foundation/src/Testing/DatabaseTruncation.php +++ b/src/foundation/src/Testing/DatabaseTruncation.php @@ -30,7 +30,7 @@ protected function truncateDatabaseTables(): void if (! RefreshDatabaseState::$migrated) { $this->artisan('migrate:fresh', $this->migrateFreshUsing()); - $this->app[Kernel::class]->setArtisan(null); + $this->app->make(Kernel::class)->setArtisan(null); RefreshDatabaseState::$migrated = true; @@ -151,7 +151,7 @@ protected function tablesToTruncate(ConnectionInterface $connection, ?string $co */ protected function exceptTables(ConnectionInterface $connection, ?string $connectionName): array { - $migrations = $this->app['config']->get('database.migrations'); + $migrations = $this->app->make('config')->get('database.migrations'); $migrationsTable = is_array($migrations) ? ($migrations['table'] ?? 'migrations') : $migrations; $migrationsTable = $connection->getTablePrefix() . $migrationsTable; diff --git a/src/foundation/src/Testing/WithConsoleEvents.php b/src/foundation/src/Testing/WithConsoleEvents.php index f9c4ba368..2c8013dd0 100644 --- a/src/foundation/src/Testing/WithConsoleEvents.php +++ b/src/foundation/src/Testing/WithConsoleEvents.php @@ -13,6 +13,6 @@ trait WithConsoleEvents */ protected function setUpWithConsoleEvents(): void { - $this->app[ConsoleKernel::class]->rerouteSymfonyCommandEvents(); + $this->app->make(ConsoleKernel::class)->rerouteSymfonyCommandEvents(); } } diff --git a/src/log/src/Context/ContextServiceProvider.php b/src/log/src/Context/ContextServiceProvider.php index ce3790dbb..cffa5b3d5 100644 --- a/src/log/src/Context/ContextServiceProvider.php +++ b/src/log/src/Context/ContextServiceProvider.php @@ -40,7 +40,7 @@ public function boot(): void }); // IMPORTANT: Uses Laravel's payload key for cross-framework queue interoperability. - $this->app['events']->listen(JobProcessing::class, function (JobProcessing $event): void { + $this->app->make('events')->listen(JobProcessing::class, function (JobProcessing $event): void { $context = $event->job->payload()['illuminate:log:context'] ?? null; if ($context !== null || Repository::hasInstance()) { diff --git a/src/log/src/LogManager.php b/src/log/src/LogManager.php index 2c4787ac8..2fb02585f 100644 --- a/src/log/src/LogManager.php +++ b/src/log/src/LogManager.php @@ -103,7 +103,7 @@ public function stack(array $channels, ?string $channel = null): LoggerInterface return (new Logger( $monolog, - $this->app['events'] + $this->app->make('events') ))->withContext($this->sharedContext()); } @@ -153,7 +153,7 @@ protected function createLogger(?string $name, ?array $config = null, bool $cach $logger = $this->tap( $config, - new Logger($this->resolve($name, $config), $this->app['events']) + new Logger($this->resolve($name, $config), $this->app->make('events')) )->withContext($this->sharedContext()); $underlyingLogger = $logger->getLogger(); @@ -212,7 +212,7 @@ protected function createEmergencyLogger(): LoggerInterface return new Logger( new Monolog('hypervel', $this->prepareHandlers([$handler])), - $this->app['events'] + $this->app->make('events') ); } diff --git a/src/queue/src/Console/ClearCommand.php b/src/queue/src/Console/ClearCommand.php index fea947e58..9016a8b58 100644 --- a/src/queue/src/Console/ClearCommand.php +++ b/src/queue/src/Console/ClearCommand.php @@ -48,7 +48,7 @@ public function handle(): ?int // connection being run for the queue operation currently being executed. $queueName = $this->getQueue($connection); - $queue = $this->hypervel['queue']->connection($connection); + $queue = $this->hypervel->make('queue')->connection($connection); if ($queue instanceof ClearableQueue) { $count = $queue->clear($queueName); diff --git a/src/queue/src/Console/RetryCommand.php b/src/queue/src/Console/RetryCommand.php index d7c6b0e3a..cbfa0d48d 100644 --- a/src/queue/src/Console/RetryCommand.php +++ b/src/queue/src/Console/RetryCommand.php @@ -53,7 +53,7 @@ public function handle(): void if (is_null($job)) { $this->components->error("Unable to find failed job with ID [{$id}]."); } else { - $this->hypervel['events']->dispatch(new JobRetryRequested($job)); + $this->hypervel->make('events')->dispatch(new JobRetryRequested($job)); $this->components->task($id, fn () => $this->retryJob($job)); @@ -127,7 +127,7 @@ protected function getJobIdsByRanges(array $ranges): array */ protected function retryJob(stdClass $job): void { - $queue = $this->hypervel['queue']->connection($job->connection); + $queue = $this->hypervel->make('queue')->connection($job->connection); $queue->pushRaw( $this->refreshRetryUntil($this->resetAttempts($job->payload)), diff --git a/src/queue/src/Console/WorkCommand.php b/src/queue/src/Console/WorkCommand.php index 996e7f2fc..c25c07ade 100644 --- a/src/queue/src/Console/WorkCommand.php +++ b/src/queue/src/Console/WorkCommand.php @@ -175,19 +175,21 @@ protected function listenForEvents(): void return; } - $this->hypervel['events']->listen(JobProcessing::class, static function (JobProcessing $event): void { + $events = $this->hypervel->make('events'); + + $events->listen(JobProcessing::class, static function (JobProcessing $event): void { static::currentCommand()?->writeOutput($event->job, 'starting'); }); - $this->hypervel['events']->listen(JobProcessed::class, static function (JobProcessed $event): void { + $events->listen(JobProcessed::class, static function (JobProcessed $event): void { static::currentCommand()?->writeOutput($event->job, 'success'); }); - $this->hypervel['events']->listen(JobReleasedAfterException::class, static function (JobReleasedAfterException $event): void { + $events->listen(JobReleasedAfterException::class, static function (JobReleasedAfterException $event): void { static::currentCommand()?->writeOutput($event->job, 'released_after_exception'); }); - $this->hypervel['events']->listen(JobFailed::class, static function (JobFailed $event): void { + $events->listen(JobFailed::class, static function (JobFailed $event): void { $command = static::currentCommand(); $command?->logFailedJob($event); diff --git a/src/queue/src/QueueManager.php b/src/queue/src/QueueManager.php index d74510ec7..201c57046 100644 --- a/src/queue/src/QueueManager.php +++ b/src/queue/src/QueueManager.php @@ -60,7 +60,7 @@ public function __construct( */ public function before(mixed $callback): void { - $this->app['events'] + $this->app->make('events') ->listen(Events\JobProcessing::class, $callback); } @@ -72,7 +72,7 @@ public function before(mixed $callback): void */ public function after(mixed $callback): void { - $this->app['events'] + $this->app->make('events') ->listen(Events\JobProcessed::class, $callback); } @@ -84,7 +84,7 @@ public function after(mixed $callback): void */ public function exceptionOccurred(mixed $callback): void { - $this->app['events'] + $this->app->make('events') ->listen(Events\JobExceptionOccurred::class, $callback); } @@ -96,7 +96,7 @@ public function exceptionOccurred(mixed $callback): void */ public function looping(mixed $callback): void { - $this->app['events'] + $this->app->make('events') ->listen(Events\Looping::class, $callback); } @@ -108,7 +108,7 @@ public function looping(mixed $callback): void */ public function failing(mixed $callback): void { - $this->app['events'] + $this->app->make('events') ->listen(Events\JobFailed::class, $callback); } @@ -120,7 +120,7 @@ public function failing(mixed $callback): void */ public function starting(mixed $callback): void { - $this->app['events'] + $this->app->make('events') ->listen(Events\WorkerStarting::class, $callback); } @@ -132,7 +132,7 @@ public function starting(mixed $callback): void */ public function stopping(mixed $callback): void { - $this->app['events'] + $this->app->make('events') ->listen(Events\WorkerStopping::class, $callback); } @@ -155,11 +155,11 @@ public function route(array|string $class, UnitEnum|string|null $queue = null, U public function pause(string $connection, string $queue): void { // IMPORTANT: Uses Laravel's key for cross-framework queue interoperability. - $this->app['cache'] + $this->app->make('cache') ->store() ->forever("illuminate:queue:paused:{$connection}:{$queue}", true); - $this->app['events']->dispatch( + $this->app->make('events')->dispatch( new Events\QueuePaused($connection, $queue) ); } @@ -170,11 +170,11 @@ public function pause(string $connection, string $queue): void public function pauseFor(string $connection, string $queue, DateInterval|DateTimeInterface|int $ttl): void { // IMPORTANT: Uses Laravel's key for cross-framework queue interoperability. - $this->app['cache'] + $this->app->make('cache') ->store() ->put("illuminate:queue:paused:{$connection}:{$queue}", true, $ttl); - $this->app['events']->dispatch( + $this->app->make('events')->dispatch( new Events\QueuePaused($connection, $queue, $ttl) ); } @@ -185,11 +185,11 @@ public function pauseFor(string $connection, string $queue, DateInterval|DateTim public function resume(string $connection, string $queue): void { // IMPORTANT: Uses Laravel's key for cross-framework queue interoperability. - $this->app['cache'] + $this->app->make('cache') ->store() ->forget("illuminate:queue:paused:{$connection}:{$queue}"); - $this->app['events']->dispatch( + $this->app->make('events')->dispatch( new Events\QueueResumed($connection, $queue) ); } @@ -200,7 +200,7 @@ public function resume(string $connection, string $queue): void public function isPaused(string $connection, string $queue): bool { // IMPORTANT: Uses Laravel's key for cross-framework queue interoperability. - return (bool) $this->app['cache'] + return (bool) $this->app->make('cache') ->store() ->get("illuminate:queue:paused:{$connection}:{$queue}", false); } diff --git a/src/queue/src/SyncQueue.php b/src/queue/src/SyncQueue.php index 040810ca8..46dbfdc97 100644 --- a/src/queue/src/SyncQueue.php +++ b/src/queue/src/SyncQueue.php @@ -191,7 +191,7 @@ protected function resolveJob(string $payload, ?string $queue): SyncJob protected function raiseBeforeJobEvent(JobContract $job): void { if ($this->container->bound('events')) { - $this->container['events'] + $this->container->make('events') ->dispatch(new JobProcessing($this->connectionName, $job)); } } @@ -202,7 +202,7 @@ protected function raiseBeforeJobEvent(JobContract $job): void protected function raiseAfterJobEvent(JobContract $job): void { if ($this->container->bound('events')) { - $this->container['events'] + $this->container->make('events') ->dispatch(new JobProcessed($this->connectionName, $job)); } } @@ -213,7 +213,7 @@ protected function raiseAfterJobEvent(JobContract $job): void protected function raiseJobAttemptedEvent(JobContract $job, ?Throwable $exceptionOccurred = null): void { if ($this->container->bound('events')) { - $this->container['events'] + $this->container->make('events') ->dispatch(new JobAttempted($this->connectionName, $job, $exceptionOccurred)); } } @@ -224,7 +224,7 @@ protected function raiseJobAttemptedEvent(JobContract $job, ?Throwable $exceptio protected function raiseExceptionOccurredJobEvent(JobContract $job, Throwable $e): void { if ($this->container->bound('events')) { - $this->container['events'] + $this->container->make('events') ->dispatch(new JobExceptionOccurred($this->connectionName, $job, $e)); } } diff --git a/src/sentry/src/SentryServiceProvider.php b/src/sentry/src/SentryServiceProvider.php index 2f79f4522..5498072bf 100644 --- a/src/sentry/src/SentryServiceProvider.php +++ b/src/sentry/src/SentryServiceProvider.php @@ -717,8 +717,6 @@ protected function hasSpotlightEnabled(): bool */ protected function getUserConfig(): array { - $config = $this->app['config'][static::$abstract]; - - return empty($config) ? [] : $config; + return $this->app->make('config')->array(static::$abstract); } } diff --git a/src/support/src/Facades/Cookie.php b/src/support/src/Facades/Cookie.php index 176fa736a..e70d18751 100644 --- a/src/support/src/Facades/Cookie.php +++ b/src/support/src/Facades/Cookie.php @@ -4,6 +4,7 @@ namespace Hypervel\Support\Facades; +use Hypervel\Contracts\Container\Container as ContainerContract; use UnitEnum; use function Hypervel\Support\enum_value; @@ -36,8 +37,10 @@ class Cookie extends Facade public static function has(UnitEnum|string $key): bool { $key = $key instanceof UnitEnum ? (string) enum_value($key) : $key; + /** @var ContainerContract $app */ + $app = static::$app; - return ! is_null(static::$app['request']->cookie($key)); + return ! is_null($app->make('request')->cookie($key)); } /** @@ -48,8 +51,10 @@ public static function has(UnitEnum|string $key): bool public static function get(UnitEnum|string|null $key = null, mixed $default = null): mixed { $key = $key instanceof UnitEnum ? (string) enum_value($key) : $key; + /** @var ContainerContract $app */ + $app = static::$app; - return static::$app['request']->cookie($key) ?? $default; + return $app->make('request')->cookie($key) ?? $default; } /** diff --git a/src/support/src/Facades/Date.php b/src/support/src/Facades/Date.php index e6ab0ec00..b7ad47a7a 100644 --- a/src/support/src/Facades/Date.php +++ b/src/support/src/Facades/Date.php @@ -125,7 +125,7 @@ protected static function getFacadeAccessor(): string */ protected static function resolveFacadeInstance(string $name): mixed { - if (! isset(static::$resolvedInstance[$name]) && ! isset(static::$app, static::$app[$name])) { + if (! isset(static::$resolvedInstance[$name]) && (static::$app === null || ! static::$app->bound($name))) { $class = static::DEFAULT_FACADE; static::swap(new $class); diff --git a/src/support/src/Facades/Facade.php b/src/support/src/Facades/Facade.php index 82bdf1523..68f3dc0b4 100644 --- a/src/support/src/Facades/Facade.php +++ b/src/support/src/Facades/Facade.php @@ -5,6 +5,7 @@ namespace Hypervel\Support\Facades; use Closure; +use Hypervel\Contracts\Container\Container as ContainerContract; use Hypervel\Database\Eloquent\Model; use Hypervel\Support\Arr; use Hypervel\Support\Benchmark; @@ -23,7 +24,7 @@ abstract class Facade /** * The application instance being facaded. */ - protected static $app; + protected static ?ContainerContract $app = null; /** * The resolved object instances. @@ -55,12 +56,14 @@ abstract class Facade public static function resolved(Closure $callback): void { $accessor = static::getFacadeAccessor(); + /** @var ContainerContract $app */ + $app = static::$app; - if (static::$app->resolved($accessor) === true) { - $callback(static::getFacadeRoot(), static::$app); + if ($app->resolved($accessor) === true) { + $callback(static::getFacadeRoot(), $app); } - static::$app->afterResolving($accessor, function ($service, $app) use ($callback) { + $app->afterResolving($accessor, function ($service, $app) use ($callback) { $callback($service, $app); }); } @@ -228,10 +231,10 @@ protected static function resolveFacadeInstance(string $name): mixed if (static::$app) { if (static::$cached) { - return static::$resolvedInstance[$name] = static::$app[$name]; + return static::$resolvedInstance[$name] = static::$app->make($name); } - return static::$app[$name]; + return static::$app->make($name); } return null; @@ -321,7 +324,7 @@ public static function defaultAliases(): Collection /** * Get the application instance behind the facade. */ - public static function getFacadeApplication() + public static function getFacadeApplication(): ?ContainerContract { return static::$app; } @@ -329,12 +332,10 @@ public static function getFacadeApplication() /** * Set the application instance. * - * Tests only. Replaces the worker-wide facade application reference; + * Boot or tests only. Replaces the worker-wide facade application reference; * runtime use races across coroutines and breaks every facade lookup. - * - * @param mixed $app */ - public static function setFacadeApplication($app): void + public static function setFacadeApplication(?ContainerContract $app): void { static::$app = $app; } diff --git a/src/support/src/Facades/Queue.php b/src/support/src/Facades/Queue.php index 5c0569d19..2b753434e 100644 --- a/src/support/src/Facades/Queue.php +++ b/src/support/src/Facades/Queue.php @@ -4,6 +4,7 @@ namespace Hypervel\Support\Facades; +use Hypervel\Contracts\Container\Container as ContainerContract; use Hypervel\Queue\Worker; use Hypervel\Support\Testing\Fakes\QueueFake; @@ -119,9 +120,11 @@ public static function fake(array|string $jobsToFake = []): QueueFake $actualQueueManager = static::isFake() ? tap(static::getFacadeRoot(), fn ($fake) => $fake->releaseUniqueJobLocks())->queue : static::getFacadeRoot(); + /** @var ContainerContract $app */ + $app = static::getFacadeApplication(); return tap(new QueueFake( - static::getFacadeApplication(), + $app, $jobsToFake, $actualQueueManager ), function ($fake) { diff --git a/src/support/src/Facades/Schema.php b/src/support/src/Facades/Schema.php index 993c9751e..fd9b3e5f6 100644 --- a/src/support/src/Facades/Schema.php +++ b/src/support/src/Facades/Schema.php @@ -4,6 +4,9 @@ namespace Hypervel\Support\Facades; +use Hypervel\Contracts\Container\Container as ContainerContract; +use Hypervel\Database\Schema\Builder; + /** * @method static void blueprintResolver(\Closure $resolver) * @method static void create(string $table, \Closure $callback) @@ -72,9 +75,12 @@ class Schema extends Facade /** * Get a schema builder instance for a connection. */ - public static function connection(?string $name = null): \Hypervel\Database\Schema\Builder + public static function connection(?string $name = null): Builder { - return static::$app['db']->connection($name)->getSchemaBuilder(); + /** @var ContainerContract $app */ + $app = static::$app; + + return $app->make('db')->connection($name)->getSchemaBuilder(); } /** diff --git a/src/support/src/Facades/Storage.php b/src/support/src/Facades/Storage.php index 15a52fdd3..ed1385566 100644 --- a/src/support/src/Facades/Storage.php +++ b/src/support/src/Facades/Storage.php @@ -4,6 +4,7 @@ namespace Hypervel\Support\Facades; +use Hypervel\Contracts\Container\Container as ContainerContract; use Hypervel\Filesystem\Filesystem; use Hypervel\Filesystem\FilesystemAdapter; use UnitEnum; @@ -116,9 +117,11 @@ public static function fake(UnitEnum|string|null $disk = null, array $config = [ if ($disk instanceof UnitEnum) { $disk = (string) enum_value($disk); } + /** @var ContainerContract $app */ + $app = static::$app; $disk = $disk === null || $disk === '' - ? static::$app['config']->get('filesystems.default') + ? $app->make('config')->string('filesystems.default') : $disk; $root = self::getRootPath($disk); @@ -157,9 +160,11 @@ public static function persistentFake(UnitEnum|string|null $disk = null, array $ if ($disk instanceof UnitEnum) { $disk = (string) enum_value($disk); } + /** @var ContainerContract $app */ + $app = static::$app; $disk = $disk === null || $disk === '' - ? static::$app['config']->get('filesystems.default') + ? $app->make('config')->string('filesystems.default') : $disk; static::set($disk, $fake = static::createLocalDriver( @@ -182,7 +187,9 @@ protected static function getRootPath(string $disk): string */ protected static function buildDiskConfiguration(string $disk, array $config, string $root): array { - $originalConfig = static::$app['config']["filesystems.disks.{$disk}"] ?? []; + /** @var ContainerContract $app */ + $app = static::$app; + $originalConfig = $app->make('config')->get("filesystems.disks.{$disk}") ?? []; return array_merge( ['throw' => $originalConfig['throw'] ?? false], diff --git a/src/support/src/ServiceProvider.php b/src/support/src/ServiceProvider.php index 1307dba65..c4a89e748 100644 --- a/src/support/src/ServiceProvider.php +++ b/src/support/src/ServiceProvider.php @@ -239,9 +239,10 @@ protected function loadRoutesFrom(string $path): void protected function loadViewsFrom(array|string $path, string $namespace): void { $this->callAfterResolving(ViewFactoryContract::class, function ($view) use ($path, $namespace) { - if (isset($this->app->config['view']['paths']) - && is_array($this->app->config['view']['paths'])) { - foreach ($this->app->config['view']['paths'] as $viewPath) { + $config = $this->app->make('config'); + + if (is_array($viewPaths = $config->get('view.paths'))) { + foreach ($viewPaths as $viewPath) { if (is_dir($appPath = $viewPath . '/vendor/' . $namespace)) { $view->addNamespace($namespace, $appPath); } diff --git a/src/testbench/src/Attributes/UsesVendor.php b/src/testbench/src/Attributes/UsesVendor.php index f033d4c32..82a688c03 100644 --- a/src/testbench/src/Attributes/UsesVendor.php +++ b/src/testbench/src/Attributes/UsesVendor.php @@ -24,7 +24,7 @@ public function beforeEach(ApplicationContract $app): void (new CreateVendorSymlink(package_path('vendor')))->handle($hypervel); - $this->vendorSymlinkCreated = $hypervel['TESTBENCH_VENDOR_SYMLINK'] ?? false; + $this->vendorSymlinkCreated = $hypervel->make('TESTBENCH_VENDOR_SYMLINK'); } public function afterEach(ApplicationContract $app): void diff --git a/src/testbench/src/Concerns/HandlesDatabases.php b/src/testbench/src/Concerns/HandlesDatabases.php index 3659d065d..945a4f19c 100644 --- a/src/testbench/src/Concerns/HandlesDatabases.php +++ b/src/testbench/src/Concerns/HandlesDatabases.php @@ -33,7 +33,7 @@ protected function setUpDatabaseRequirements(Closure $callback): void attribute: fn () => $this->parseTestMethodAttributes($app, RequiresDatabase::class), ); - $app['events']->listen(DatabaseRefreshed::class, function () { + $app->make('events')->listen(DatabaseRefreshed::class, function () { $this->defineDatabaseMigrationsAfterDatabaseRefreshed(); }); diff --git a/src/testbench/src/Concerns/InteractsWithPublishedFiles.php b/src/testbench/src/Concerns/InteractsWithPublishedFiles.php index 4ad86d982..987e37344 100644 --- a/src/testbench/src/Concerns/InteractsWithPublishedFiles.php +++ b/src/testbench/src/Concerns/InteractsWithPublishedFiles.php @@ -64,7 +64,7 @@ protected function tearDownInteractsWithPublishedFiles(): void protected function cacheExistingMigrationsFiles(): void { $this->cachedExistingMigrationsFiles ??= (new Collection( - $this->app['files']->files($this->app->databasePath('migrations')) + $this->app->make('files')->files($this->app->databasePath('migrations')) ))->map($this->publishedFilePath(...)) ->filter(static fn (string $file) => str_ends_with($file, '.php')) ->all(); @@ -79,7 +79,7 @@ protected function assertFileContains(array $contains, string $file, string $mes { $this->assertFilenameExists($file); - $haystack = $this->app['files']->get( + $haystack = $this->app->make('files')->get( $this->app->basePath($file) ); @@ -97,7 +97,7 @@ protected function assertFileDoesNotContains(array $contains, string $file, stri { $this->assertFilenameExists($file); - $haystack = $this->app['files']->get( + $haystack = $this->app->make('files')->get( $this->app->basePath($file) ); @@ -127,7 +127,7 @@ protected function assertMigrationFileContains(array $contains, string $file, st $this->assertTrue(! is_null($migrationFile), "Assert migration file {$file} does exist"); - $haystack = $this->app['files']->get($migrationFile); + $haystack = $this->app->make('files')->get($migrationFile); foreach ($contains as $needle) { $this->assertStringContainsString($needle, $haystack, $message); @@ -145,7 +145,7 @@ protected function assertMigrationFileDoesNotContains(array $contains, string $f $this->assertTrue(! is_null($migrationFile), "Assert migration file {$file} does exist"); - $haystack = $this->app['files']->get($migrationFile); + $haystack = $this->app->make('files')->get($migrationFile); foreach ($contains as $needle) { $this->assertStringNotContainsString($needle, $haystack, $message); @@ -169,7 +169,7 @@ protected function assertFilenameExists(string $file): void { $appFile = $this->app->basePath($file); - $this->assertTrue($this->app['files']->exists($appFile), "Assert file {$file} does exist"); + $this->assertTrue($this->app->make('files')->exists($appFile), "Assert file {$file} does exist"); } /** @@ -179,7 +179,7 @@ protected function assertFilenameDoesNotExists(string $file): void { $appFile = $this->app->basePath($file); - $this->assertTrue(! $this->app['files']->exists($appFile), "Assert file {$file} doesn't exist"); + $this->assertTrue(! $this->app->make('files')->exists($appFile), "Assert file {$file} doesn't exist"); } /** @@ -256,7 +256,7 @@ protected function findFirstPublishedMigrationFile(string $filename, ?string $di ? $this->app->basePath($directory) : $this->app->databasePath('migrations'); - return $this->app['files']->glob(join_paths($migrationPath, "*{$filename}"))[0] ?? null; + return $this->app->make('files')->glob(join_paths($migrationPath, "*{$filename}"))[0] ?? null; } /** diff --git a/src/testing/src/Concerns/TestCaches.php b/src/testing/src/Concerns/TestCaches.php index b907c2af3..a0f4cdc3b 100644 --- a/src/testing/src/Concerns/TestCaches.php +++ b/src/testing/src/Concerns/TestCaches.php @@ -29,7 +29,7 @@ protected function parallelSafeCachePrefix(): string { $token = ParallelTesting::token(); $suffix = "test_{$token}_"; - $prefix = $this->app->make('config')->string('cache.prefix', ''); + $prefix = $this->app->make('config')->string('cache.prefix'); return str_ends_with($prefix, $suffix) ? $prefix @@ -41,6 +41,6 @@ protected function parallelSafeCachePrefix(): string */ protected function switchToCachePrefix(string $prefix): void { - $this->app['config']->set('cache.prefix', $prefix); + $this->app->make('config')->set('cache.prefix', $prefix); } } diff --git a/src/testing/src/Concerns/TestViews.php b/src/testing/src/Concerns/TestViews.php index 3787f1f38..6506458f3 100644 --- a/src/testing/src/Concerns/TestViews.php +++ b/src/testing/src/Concerns/TestViews.php @@ -38,7 +38,7 @@ protected function bootTestViews(): void */ protected function parallelSafeCompiledViewPath(): ?string { - $path = $this->app->make('config')->string('view.compiled', ''); + $path = $this->app->make('config')->string('view.compiled'); if (! $path) { return null; @@ -57,10 +57,10 @@ protected function parallelSafeCompiledViewPath(): ?string */ protected function switchToCompiledViewPath(string $path): void { - $this->app['config']->set('view.compiled', $path); + $this->app->make('config')->set('view.compiled', $path); if ($this->app->resolved('blade.compiler')) { - $compiler = $this->app['blade.compiler']; + $compiler = $this->app->make('blade.compiler'); (function () use ($path) { $this->cachePath = $path; /* @phpstan-ignore property.notFound */ diff --git a/src/testing/src/PendingCommand.php b/src/testing/src/PendingCommand.php index 0cadad5c4..9f3d47793 100644 --- a/src/testing/src/PendingCommand.php +++ b/src/testing/src/PendingCommand.php @@ -382,7 +382,7 @@ public function run(): int } finally { $this->flushExpectations(); - $this->app->offsetUnset(OutputStyle::class); + $this->app->forgetInstance(OutputStyle::class); } } @@ -475,7 +475,7 @@ protected function mockConsoleOutput() }); } - $this->app->bind(OutputStyle::class, fn () => $mock); + $this->app->instance(OutputStyle::class, $mock); return $mock; } diff --git a/src/validation/src/ValidationServiceProvider.php b/src/validation/src/ValidationServiceProvider.php index f6d1273ae..ce503ec26 100644 --- a/src/validation/src/ValidationServiceProvider.php +++ b/src/validation/src/ValidationServiceProvider.php @@ -30,13 +30,13 @@ public function register(): void protected function registerValidationFactory(): void { $this->app->singleton('validator', function ($app) { - $validator = new Factory($app['translator'], $app); + $validator = new Factory($app->make('translator'), $app); // The validation presence verifier is responsible for determining the existence of // values in a given data collection which is typically a relational database or // other persistent data stores. It is used to check for "uniqueness" as well. - if (isset($app['db'], $app['validation.presence'])) { - $validator->setPresenceVerifier($app['validation.presence']); + if ($app->bound('db') && $app->bound('validation.presence')) { + $validator->setPresenceVerifier($app->make('validation.presence')); } return $validator; @@ -49,7 +49,7 @@ protected function registerValidationFactory(): void protected function registerPresenceVerifier(): void { $this->app->singleton('validation.presence', function ($app) { - return new DatabasePresenceVerifier($app['db']); + return new DatabasePresenceVerifier($app->make('db')); }); } diff --git a/tests/Auth/EnsureEmailIsVerifiedTest.php b/tests/Auth/EnsureEmailIsVerifiedTest.php index fad7adbbb..93564f588 100644 --- a/tests/Auth/EnsureEmailIsVerifiedTest.php +++ b/tests/Auth/EnsureEmailIsVerifiedTest.php @@ -36,9 +36,9 @@ public function testVerifiedUserPassesThrough() $this->assertSame($expectedResponse, $result); } - public function testUserThatDoesNotImplementMustVerifyEmailPassesThrough() + public function testUserThatDoesNotImplementMustVerifyEmailPassesThrough(): void { - // User implements Authenticatable but NOT MustVerifyEmail + // User implements Authenticatable but does not implement MustVerifyEmail. $user = m::mock(Authenticatable::class); $request = m::mock(Request::class); @@ -78,10 +78,10 @@ public function testUnverifiedUserReturnsJsonWhenExpectsJson() $middleware->handle($request, fn () => new Response('should not reach')); } - public function testUnverifiedUserRedirectsWhenNotJson() + public function testUnverifiedUserRedirectsWhenNotJson(): void { // Register a named route so URL::route() can resolve it - $this->app['router']->get('/email/verify', fn () => 'verify')->name('verify.email'); + $this->app->make('router')->get('/email/verify', fn () => 'verify')->name('verify.email'); $user = m::mock(Authenticatable::class . ',' . MustVerifyEmail::class); $user->shouldReceive('hasVerifiedEmail')->andReturnFalse(); @@ -96,9 +96,9 @@ public function testUnverifiedUserRedirectsWhenNotJson() $this->assertSame(302, $result->getStatusCode()); } - public function testGuestRequestRedirectsWhenNotJson() + public function testGuestRequestRedirectsWhenNotJson(): void { - $this->app['router']->get('/email/verify', fn () => 'verify')->name('verify.email'); + $this->app->make('router')->get('/email/verify', fn () => 'verify')->name('verify.email'); $request = m::mock(Request::class); $request->shouldReceive('user')->andReturn(null); diff --git a/tests/Cache/ClearCommandTest.php b/tests/Cache/ClearCommandTest.php index 2c1292b85..2be571590 100644 --- a/tests/Cache/ClearCommandTest.php +++ b/tests/Cache/ClearCommandTest.php @@ -31,7 +31,7 @@ protected function setUp(): void parent::setUp(); $app = new Application; - $app['path.storage'] = __DIR__; + $app->instance('path.storage', __DIR__); $this->cacheManager = m::mock(CacheManager::class); $this->files = m::mock(Filesystem::class); diff --git a/tests/Concurrency/ConcurrencyTest.php b/tests/Concurrency/ConcurrencyTest.php index b078f4a04..2d71f0f4a 100644 --- a/tests/Concurrency/ConcurrencyTest.php +++ b/tests/Concurrency/ConcurrencyTest.php @@ -321,6 +321,19 @@ public function testManagerDefaultDriverIsCoroutine() $this->assertSame('coroutine', $manager->getDefaultInstance()); } + public function testChangingDefaultDriverPreservesDriverConfiguration(): void + { + $manager = $this->app->make(ConcurrencyManager::class); + $config = $this->app->make('config'); + $driverConfig = ['driver' => 'sync', 'option' => 'preserved']; + $config->set('concurrency.driver.sync', $driverConfig); + + $manager->setDefaultInstance('sync'); + + $this->assertSame('sync', $manager->getDefaultInstance()); + $this->assertSame($driverConfig, $manager->getInstanceConfig('sync')); + } + public function testManagerResolvesCoroutineDriver() { $manager = $this->app->make(ConcurrencyManager::class); diff --git a/tests/Container/ContainerExtendTest.php b/tests/Container/ContainerExtendTest.php index fe9017794..602874626 100644 --- a/tests/Container/ContainerExtendTest.php +++ b/tests/Container/ContainerExtendTest.php @@ -10,10 +10,10 @@ class ContainerExtendTest extends TestCase { - public function testExtendedBindings() + public function testExtendedBindings(): void { $container = new Container; - $container['foo'] = 'foo'; + $container->bind('foo', fn () => 'foo'); $container->extend('foo', function ($old, $container) { return $old . 'bar'; }); @@ -34,7 +34,7 @@ public function testExtendedBindings() $result = $container->make('foo'); $this->assertSame('taylor', $result->name); - $this->assertEquals(26, $result->age); + $this->assertSame(26, $result->age); $this->assertSame($result, $container->make('foo')); } @@ -83,13 +83,13 @@ public function testExtendIsLazyInitialized() $this->assertTrue(ContainerLazyExtendStub::$initialized); } - public function testExtendCanBeCalledBeforeBind() + public function testExtendCanBeCalledBeforeBind(): void { $container = new Container; $container->extend('foo', function ($old, $container) { return $old . 'bar'; }); - $container['foo'] = 'foo'; + $container->bind('foo', fn () => 'foo'); $this->assertSame('foobar', $container->make('foo')); } @@ -150,10 +150,10 @@ public function testExtensionWorksOnAliasedBindings() $this->assertSame('some value extended', $container->make('something')); } - public function testMultipleExtends() + public function testMultipleExtends(): void { $container = new Container; - $container['foo'] = 'foo'; + $container->bind('foo', fn () => 'foo'); $container->extend('foo', function ($old, $container) { return $old . 'bar'; }); @@ -164,7 +164,8 @@ public function testMultipleExtends() $this->assertSame('foobarbaz', $container->make('foo')); } - public function testUnsetExtend() + // Upstream: testUnsetExtend; Hypervel tests forgetExtenders() without unsupported container unset. + public function testForgetExtenders(): void { $container = new Container; $container->bind('foo', function () { @@ -180,7 +181,6 @@ public function testUnsetExtend() return $obj; }); - unset($container['foo']); $container->forgetExtenders('foo'); $container->bind('foo', function () { diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index 007e081b9..b71e34a2d 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -308,33 +308,12 @@ public function testContainerIsPassedToResolvers() $this->assertSame($c, $container); } - public function testArrayAccess() - { - $container = new Container; - $this->assertFalse(isset($container['something'])); - $container['something'] = function () { - return 'foo'; - }; - $this->assertTrue(isset($container['something'])); - $this->assertNotEmpty($container['something']); - $this->assertSame('foo', $container['something']); - unset($container['something']); - $this->assertFalse(isset($container['something'])); + // REMOVED: Container ArrayAccess is intentionally unsupported; use named container methods. - // test offsetSet when it's not instanceof Closure - $container = new Container; - $container['something'] = 'text'; - $this->assertTrue(isset($container['something'])); - $this->assertNotEmpty($container['something']); - $this->assertSame('text', $container['something']); - unset($container['something']); - $this->assertFalse(isset($container['something'])); - } - - public function testAliases() + public function testAliases(): void { $container = new Container; - $container['foo'] = 'bar'; + $container->bind('foo', fn () => 'bar'); $container->alias('foo', 'baz'); $container->alias('baz', 'bat'); $this->assertSame('bar', $container->make('foo')); @@ -352,12 +331,12 @@ public function testAliasesWithArrayOfParameters() $this->assertEquals([1, 2, 3], $container->make('baz', [1, 2, 3])); } - public function testBindingsCanBeOverridden() + public function testBindingsCanBeOverridden(): void { $container = new Container; - $container['foo'] = 'bar'; - $container['foo'] = 'baz'; - $this->assertSame('baz', $container['foo']); + $container->bind('foo', fn () => 'bar'); + $container->bind('foo', fn () => 'baz'); + $this->assertSame('baz', $container->make('foo')); } public function testBindingAnInstanceReturnsTheInstance() @@ -533,23 +512,17 @@ public function testBound() $this->assertFalse($container->bound(ContainerConcreteStub::class)); } - public function testUnsetRemoveBoundInstances() - { - $container = new Container; - $container->instance('object', new stdClass); - unset($container['object']); - - $this->assertFalse($container->bound('object')); - } + // REMOVED: Instance-forgetting coverage is consolidated in testForgetInstanceForgetsInstance. - public function testBoundInstanceAndAliasCheckViaArrayAccess() + // Upstream: testBoundInstanceAndAliasCheckViaArrayAccess; Hypervel uses named binding checks. + public function testBoundInstanceAndAliasCheck(): void { $container = new Container; $container->instance('object', new stdClass); $container->alias('object', 'alias'); - $this->assertTrue(isset($container['object'])); - $this->assertTrue(isset($container['alias'])); + $this->assertTrue($container->bound('object')); + $this->assertTrue($container->bound('alias')); } public function testReboundListeners() @@ -649,13 +622,15 @@ public function testBindingResolutionExceptionMessageWhenClassDoesNotExist() $container->build('Foo\Bar\Baz\DummyClass'); } - public function testForgetInstanceForgetsInstance() + public function testForgetInstanceForgetsInstance(): void { $container = new Container; $containerConcreteStub = new ContainerConcreteStub; $container->instance(ContainerConcreteStub::class, $containerConcreteStub); + $this->assertTrue($container->bound(ContainerConcreteStub::class)); $this->assertTrue($container->isShared(ContainerConcreteStub::class)); $container->forgetInstance(ContainerConcreteStub::class); + $this->assertFalse($container->bound(ContainerConcreteStub::class)); $this->assertFalse($container->isShared(ContainerConcreteStub::class)); } @@ -825,30 +800,6 @@ public function testRebindingScopedBindingClearsStaleContextInstance() $this->assertInstanceOf(ContainerImplementationStubTwo::class, $second); } - public function testOffsetUnsetClearsScopedInstance() - { - $container = new Container; - $container->scoped(ContainerConcreteStub::class); - - $first = $container->make(ContainerConcreteStub::class); - - unset($container[ContainerConcreteStub::class]); - - $second = $container->make(ContainerConcreteStub::class); - - $this->assertNotSame($first, $second); - } - - public function testOffsetUnsetClearsScopedLifecycleMarker(): void - { - $container = new Container; - $container->scoped(ContainerConcreteStub::class); - - unset($container[ContainerConcreteStub::class]); - - $this->assertFalse($container->isScoped(ContainerConcreteStub::class)); - } - public function testExtendingResolvedAutoSingletonUpdatesCachedInstance(): void { $container = new Container; @@ -1135,14 +1086,7 @@ public function testContainerCanBindAnyWord() $this->assertInstanceOf(stdClass::class, $container->get('Taylor')); } - public function testContainerCanDynamicallySetService() - { - $container = new Container; - $this->assertFalse(isset($container['name'])); - $container['name'] = 'Taylor'; - $this->assertTrue(isset($container['name'])); - $this->assertSame('Taylor', $container['name']); - } + // REMOVED: Container ArrayAccess is intentionally unsupported; use named container methods. public function testUnknownEntryThrowsException() { diff --git a/tests/Fortify/AuthenticatedSessionControllerWithTwoFactorTest.php b/tests/Fortify/AuthenticatedSessionControllerWithTwoFactorTest.php index e3d648ce2..70abb8fad 100644 --- a/tests/Fortify/AuthenticatedSessionControllerWithTwoFactorTest.php +++ b/tests/Fortify/AuthenticatedSessionControllerWithTwoFactorTest.php @@ -135,7 +135,7 @@ public function testUserCanAuthenticateWhenTwoFactorChallengeIsDisabled(): void public function testRehashUserPasswordWhenRedirectingToTwoFactorChallengeIfRehashingOnLoginIsEnabled(): void { - $this->app['config']->set('hashing.rehash_on_login', true); + $this->app->make('config')->set('hashing.rehash_on_login', true); $user = UserWithTwoFactor::forceCreate([ 'name' => 'Taylor Otwell', @@ -157,7 +157,7 @@ public function testRehashUserPasswordWhenRedirectingToTwoFactorChallengeIfRehas public function testDoesNotRehashUserPasswordWhenRedirectingToTwoFactorChallengeIfRehashingOnLoginIsDisabled(): void { - $this->app['config']->set('hashing.rehash_on_login', false); + $this->app->make('config')->set('hashing.rehash_on_login', false); $user = UserWithTwoFactor::forceCreate([ 'name' => 'Taylor Otwell', diff --git a/tests/Foundation/ApplicationRunningInConsoleTest.php b/tests/Foundation/ApplicationRunningInConsoleTest.php index e31be6c98..aac00be72 100644 --- a/tests/Foundation/ApplicationRunningInConsoleTest.php +++ b/tests/Foundation/ApplicationRunningInConsoleTest.php @@ -309,7 +309,7 @@ public function testRunningConsoleCommandReturnsFalseWhenNoArgvSet() // detectEnvironment integration // ------------------------------------------------------------------ - public function testDetectEnvironmentUsesArgvWhenInConsole() + public function testDetectEnvironmentUsesArgvWhenInConsole(): void { $_SERVER['argv'] = ['artisan', '--env=staging']; $app = new Application; @@ -318,6 +318,7 @@ public function testDetectEnvironmentUsesArgvWhenInConsole() $result = $app->detectEnvironment(fn () => 'default'); $this->assertSame('staging', $result); + $this->assertSame('staging', $app->environment()); } public function testDetectEnvironmentIgnoresArgvWhenNotInConsole() diff --git a/tests/Foundation/Bootstrap/LoadConfigurationTest.php b/tests/Foundation/Bootstrap/LoadConfigurationTest.php index 01b7a4ae3..80a5b17e4 100644 --- a/tests/Foundation/Bootstrap/LoadConfigurationTest.php +++ b/tests/Foundation/Bootstrap/LoadConfigurationTest.php @@ -17,16 +17,16 @@ class LoadConfigurationTest extends TestCase { - public function testLoadsBaseConfiguration() + public function testLoadsBaseConfiguration(): void { $app = new Application; (new LoadConfiguration)->bootstrap($app); - $this->assertSame('Hypervel', $app['config']['app.name']); + $this->assertSame('Hypervel', $app->make('config')->string('app.name')); } - public function testSetsEnvironmentResolver() + public function testSetsEnvironmentResolver(): void { $app = new Application; $this->assertNull((new ReflectionClass($app))->getProperty('environmentResolver')->getValue($app)); @@ -39,28 +39,30 @@ public function testSetsEnvironmentResolver() ); } - public function testDontLoadBaseConfiguration() + public function testDontLoadBaseConfiguration(): void { $app = new Application; $app->dontMergeFrameworkConfiguration(); (new LoadConfiguration)->bootstrap($app); - $this->assertNull($app['config']['app.name']); + $this->assertNull($app->make('config')->get('app.name')); } - public function testLoadsConfigurationInIsolation() + public function testLoadsConfigurationInIsolation(): void { $app = new Application(__DIR__ . '/../Fixtures'); $app->useConfigPath(__DIR__ . '/../Fixtures/config'); (new LoadConfiguration)->bootstrap($app); - $this->assertNull($app['config']['bar.foo']); - $this->assertSame('bar', $app['config']['custom.foo']); + $config = $app->make('config'); + + $this->assertNull($config->get('bar.foo')); + $this->assertSame('bar', $config->string('custom.foo')); } - public function testConfigurationArrayKeysMatchLoadedFilenames() + public function testConfigurationArrayKeysMatchLoadedFilenames(): void { $baseConfigPath = dirname((new ReflectionClass(LoadConfiguration::class))->getFileName(), 3) . '/config'; $customConfigPath = __DIR__ . '/../Fixtures/config'; @@ -71,7 +73,7 @@ public function testConfigurationArrayKeysMatchLoadedFilenames() (new LoadConfiguration)->bootstrap($app); $this->assertEqualsCanonicalizing( - array_keys($app['config']->all()), + array_keys($app->make('config')->all()), collect((new Filesystem)->files([ $baseConfigPath, $customConfigPath, @@ -79,14 +81,14 @@ public function testConfigurationArrayKeysMatchLoadedFilenames() ); } - public function testShouldMergeFrameworkConfigurationDefaultsToTrue() + public function testShouldMergeFrameworkConfigurationDefaultsToTrue(): void { $app = new Application; $this->assertTrue($app->shouldMergeFrameworkConfiguration()); } - public function testDontMergeFrameworkConfigurationReturnsSelf() + public function testDontMergeFrameworkConfigurationReturnsSelf(): void { $app = new Application; @@ -96,22 +98,24 @@ public function testDontMergeFrameworkConfigurationReturnsSelf() $this->assertFalse($app->shouldMergeFrameworkConfiguration()); } - public function testBaseConfigurationIncludesCoreFrameworkConfigs() + public function testBaseConfigurationIncludesCoreFrameworkConfigs(): void { $app = new Application; (new LoadConfiguration)->bootstrap($app); + $config = $app->make('config'); + // All centralized framework configs should be loaded foreach (['app', 'auth', 'cache', 'database', 'logging', 'session', 'view'] as $key) { $this->assertNotNull( - $app['config'][$key], + $config->get($key), "Framework config '{$key}' should be loaded by LoadConfiguration." ); } } - public function testDontMergeFrameworkConfigurationSkipsAllBaseConfigs() + public function testDontMergeFrameworkConfigurationSkipsAllBaseConfigs(): void { $app = new Application; $app->dontMergeFrameworkConfiguration(); @@ -119,23 +123,27 @@ public function testDontMergeFrameworkConfigurationSkipsAllBaseConfigs() (new LoadConfiguration)->bootstrap($app); // No base config should be present (app has no config dir with files) - $this->assertNull($app['config']['auth']); - $this->assertNull($app['config']['cache']); - $this->assertNull($app['config']['database']); + $config = $app->make('config'); + + $this->assertNull($config->get('auth')); + $this->assertNull($config->get('cache')); + $this->assertNull($config->get('database')); } - public function testAppConfigOverridesBaseConfigValues() + public function testAppConfigOverridesBaseConfigValues(): void { $app = new Application(__DIR__ . '/../Fixtures'); $app->useConfigPath(__DIR__ . '/../Fixtures/config'); (new LoadConfiguration)->bootstrap($app); + $config = $app->make('config'); + // custom.php is app-specific, should be loaded - $this->assertSame('bar', $app['config']['custom.foo']); + $this->assertSame('bar', $config->string('custom.foo')); // Base configs should still be loaded for keys not in the app config dir - $this->assertNotNull($app['config']['auth']); + $this->assertNotNull($config->get('auth')); } public function testFailedReloadRestoresThePreviousRepositoryAndException(): void diff --git a/tests/Foundation/Console/KernelTerminateTest.php b/tests/Foundation/Console/KernelTerminateTest.php index c027ac786..eabd0bea1 100644 --- a/tests/Foundation/Console/KernelTerminateTest.php +++ b/tests/Foundation/Console/KernelTerminateTest.php @@ -237,7 +237,9 @@ public function testDurationThresholdWithDateTimeInterfaceNotExceeded(): void public function testTerminateUsesConfiguredTimezone(): void { - $this->app['config']->set('app.timezone', 'UTC'); + $config = $this->app->make('config'); + + $config->set('app.timezone', 'UTC'); $startedAt = null; $kernel = $this->app->make(KernelContract::class); @@ -248,7 +250,7 @@ public function testTerminateUsesConfiguredTimezone(): void $this->assertSame($started, $kernel->commandStartedAt()); }); - $this->app['config']->set('app.timezone', 'Australia/Melbourne'); + $config->set('app.timezone', 'Australia/Melbourne'); CarbonImmutable::setTestNow(CarbonImmutable::now()); $input = new StringInput('foo'); diff --git a/tests/Foundation/FoundationApplicationTest.php b/tests/Foundation/FoundationApplicationTest.php index ae69f3462..0376f99f9 100644 --- a/tests/Foundation/FoundationApplicationTest.php +++ b/tests/Foundation/FoundationApplicationTest.php @@ -332,7 +332,7 @@ public function testDebugHelper() $this->assertTrue($debugOn->hasDebugModeEnabled()); } - public function testBeforeBootstrappingAddsClosure() + public function testBeforeBootstrappingAddsClosure(): void { $app = new Application; $eventDispatcher = new EventDispatcher($app); @@ -340,10 +340,10 @@ public function testBeforeBootstrappingAddsClosure() $closure = function () {}; $app->beforeBootstrapping(RegisterFacades::class, $closure); - $this->assertArrayHasKey(0, $app['events']->getListeners('bootstrapping: Hypervel\Foundation\Bootstrap\RegisterFacades')); + $this->assertArrayHasKey(0, $app->make('events')->getListeners('bootstrapping: Hypervel\Foundation\Bootstrap\RegisterFacades')); } - public function testAfterBootstrappingAddsClosure() + public function testAfterBootstrappingAddsClosure(): void { $app = new Application; $eventDispatcher = new EventDispatcher($app); @@ -351,7 +351,7 @@ public function testAfterBootstrappingAddsClosure() $closure = function () {}; $app->afterBootstrapping(RegisterFacades::class, $closure); - $this->assertArrayHasKey(0, $app['events']->getListeners('bootstrapped: Hypervel\Foundation\Bootstrap\RegisterFacades')); + $this->assertArrayHasKey(0, $app->make('events')->getListeners('bootstrapped: Hypervel\Foundation\Bootstrap\RegisterFacades')); } public function testTerminationTests() @@ -815,7 +815,7 @@ public function testAbortAcceptsHeaders() } } - public function testMethodAfterLoadingEnvironmentAddsClosure() + public function testMethodAfterLoadingEnvironmentAddsClosure(): void { $app = new Application; $eventDispatcher = new EventDispatcher($app); @@ -824,7 +824,7 @@ public function testMethodAfterLoadingEnvironmentAddsClosure() $closure = function () {}; $app->afterLoadingEnvironment($closure); - $listeners = $app['events']->getListeners('bootstrapped: ' . LoadEnvironmentVariables::class); + $listeners = $app->make('events')->getListeners('bootstrapped: ' . LoadEnvironmentVariables::class); $this->assertArrayHasKey(0, $listeners); } diff --git a/tests/Foundation/FoundationDevCommandsTest.php b/tests/Foundation/FoundationDevCommandsTest.php index f3c2c9dff..0d8db6ba3 100644 --- a/tests/Foundation/FoundationDevCommandsTest.php +++ b/tests/Foundation/FoundationDevCommandsTest.php @@ -21,7 +21,7 @@ protected function setUp(): void DevCommands::flushState(); $app = new Application(__DIR__); - $app['env'] = 'testing'; + $app->instance('env', 'testing'); $app->setRunningInConsole(true); } diff --git a/tests/Foundation/FoundationHelpersTest.php b/tests/Foundation/FoundationHelpersTest.php index bde1d9f9d..c421ccd86 100644 --- a/tests/Foundation/FoundationHelpersTest.php +++ b/tests/Foundation/FoundationHelpersTest.php @@ -173,10 +173,10 @@ public function testTodayWithNull(): void $this->assertSame(CarbonImmutable::class, $result::class); } - public function testCache() + public function testCache(): void { $cache = m::mock(CacheManager::class); - $this->app['cache'] = $cache; + $this->app->instance('cache', $cache); // cache() returns the CacheManager $this->assertInstanceOf(CacheManager::class, cache()); diff --git a/tests/Foundation/FoundationViteTest.php b/tests/Foundation/FoundationViteTest.php index fdaafe1de..f8afaa677 100644 --- a/tests/Foundation/FoundationViteTest.php +++ b/tests/Foundation/FoundationViteTest.php @@ -847,7 +847,7 @@ public function testViteCanAssetPath(): void ], ], $buildDir = Str::random()); $vite = app(Vite::class)->useBuildDirectory($buildDir); - $this->app['config']->set('app.url', 'https://cdn.app.com'); + $this->app->make('config')->set('app.url', 'https://cdn.app.com'); // default behaviour... $this->assertSame("https://cdn.app.com/{$buildDir}/assets/profile.versioned.png", $vite->asset('resources/images/profile.png')); diff --git a/tests/Foundation/StaticStateTest.php b/tests/Foundation/StaticStateTest.php index ece7c563b..250bb5036 100644 --- a/tests/Foundation/StaticStateTest.php +++ b/tests/Foundation/StaticStateTest.php @@ -61,14 +61,14 @@ public function testLoadConfigurationFlushStateClearsAlwaysUseConfig(): void $app = new Application; (new LoadConfiguration)->bootstrap($app); - $this->assertSame('Static Test', $app['config']['app.name']); + $this->assertSame('Static Test', $app->make('config')->string('app.name')); LoadConfiguration::flushState(); $app = new Application; (new LoadConfiguration)->bootstrap($app); - $this->assertSame('Hypervel', $app['config']['app.name']); + $this->assertSame('Hypervel', $app->make('config')->string('app.name')); } public function testCliDumperFlushStateClearsDumpSourceResolver(): void diff --git a/tests/Foundation/Testing/Concerns/MakesHttpRequestsTest.php b/tests/Foundation/Testing/Concerns/MakesHttpRequestsTest.php index 68705fc2b..181da9b9c 100644 --- a/tests/Foundation/Testing/Concerns/MakesHttpRequestsTest.php +++ b/tests/Foundation/Testing/Concerns/MakesHttpRequestsTest.php @@ -24,15 +24,15 @@ class MakesHttpRequestsTest extends TestCase { - public function testFromSetsHeaderAndSession() + public function testFromSetsHeaderAndSession(): void { $this->from('previous/url'); $this->assertSame('previous/url', $this->defaultHeaders['referer']); - $this->assertSame('previous/url', $this->app['session']->previousUrl()); + $this->assertSame('previous/url', $this->app->make('session')->previousUrl()); } - public function testFromRouteSetsHeaderAndSession() + public function testFromRouteSetsHeaderAndSession(): void { $router = $this->app->make(Registrar::class); @@ -41,7 +41,7 @@ public function testFromRouteSetsHeaderAndSession() $this->fromRoute('previous-url'); $this->assertSame('http://localhost/previous/url', $this->defaultHeaders['referer']); - $this->assertSame('http://localhost/previous/url', $this->app['session']->previousUrl()); + $this->assertSame('http://localhost/previous/url', $this->app->make('session')->previousUrl()); } public function testFromRemoveHeader() @@ -148,6 +148,27 @@ public function testWithoutAndWithMiddlewareWithParameter() ); } + public function testWithMiddlewareRestoresExistingBinding(): void + { + $next = fn (string $request): string => $request; + + $this->app->bind( + BoundMiddleware::class, + fn () => new BoundMiddleware('FromBinding') + ); + + $this->withoutMiddleware(BoundMiddleware::class); + $this->assertInstanceOf(FakeMiddleware::class, $this->app->make(BoundMiddleware::class)); + + $this->withMiddleware(BoundMiddleware::class); + + $this->assertTrue($this->app->bound(BoundMiddleware::class)); + $this->assertSame( + 'fooFromBinding', + $this->app->make(BoundMiddleware::class)->handle('foo', $next) + ); + } + public function testWithCookieSetCookie() { $this->withCookie('foo', 'bar'); @@ -614,6 +635,18 @@ public function handle($request, $next) } } +class BoundMiddleware +{ + public function __construct(private readonly string $suffix) + { + } + + public function handle(string $request, callable $next): mixed + { + return $next($request . $this->suffix); + } +} + class TerminatingMiddleware { public static $callback; diff --git a/tests/Foundation/Testing/DatabaseTruncationTest.php b/tests/Foundation/Testing/DatabaseTruncationTest.php index b186f9b12..9211f423a 100644 --- a/tests/Foundation/Testing/DatabaseTruncationTest.php +++ b/tests/Foundation/Testing/DatabaseTruncationTest.php @@ -5,6 +5,7 @@ namespace Hypervel\Tests\Foundation\Testing; use Hypervel\Config\Repository; +use Hypervel\Container\Container; use Hypervel\Contracts\Events\Dispatcher; use Hypervel\Database\Connection; use Hypervel\Database\Query\Builder as QueryBuilder; @@ -18,7 +19,7 @@ class DatabaseTruncationTest extends TestCase { use DatabaseTruncation; - private ?array $app; + private ?Container $app; private ?array $tablesToTruncate = null; @@ -28,13 +29,14 @@ protected function setUp(): void { parent::setUp(); - $this->app['config'] = new Repository([ + $this->app = new Container; + $this->app->instance('config', new Repository([ 'database' => [ 'migrations' => [ 'table' => 'migrations', ], ], - ]); + ])); } protected function tearDown(): void diff --git a/tests/Inertia/ComponentTest.php b/tests/Inertia/ComponentTest.php index 8afa46453..d01b7b41b 100644 --- a/tests/Inertia/ComponentTest.php +++ b/tests/Inertia/ComponentTest.php @@ -201,7 +201,7 @@ public function testComponentsDoNotCreateCachedViewFilesPerRequest(): void { Config::set(['inertia.ssr.enabled' => true]); - $viewCachePath = $this->app['config']['view.compiled']; + $viewCachePath = $this->app->make('config')->string('view.compiled'); $view = 'Fallback'; $this->renderView($view, ['page' => self::EXAMPLE_PAGE_OBJECT]); diff --git a/tests/Integration/Cache/Redis/PhpRedisCacheFunnelTest.php b/tests/Integration/Cache/Redis/PhpRedisCacheFunnelTest.php index f655c08ab..a4a5d3dcf 100644 --- a/tests/Integration/Cache/Redis/PhpRedisCacheFunnelTest.php +++ b/tests/Integration/Cache/Redis/PhpRedisCacheFunnelTest.php @@ -148,14 +148,15 @@ public function testFunnelReleasesSlotWithSerializationAndCompression(): void */ protected function configureLockConnection(array $options): void { - $baseConfig = $this->app['config']->get('database.redis.default'); + $config = $this->app->make('config'); + $baseConfig = $config->array('database.redis.default'); - $this->app['config']->set('database.redis.lock-test', array_merge($baseConfig, [ + $config->set('database.redis.lock-test', array_merge($baseConfig, [ 'options' => $options, ])); - $this->app['config']->set('cache.stores.redis.connection', 'default'); - $this->app['config']->set('cache.stores.redis.lock_connection', 'lock-test'); + $config->set('cache.stores.redis.connection', 'default'); + $config->set('cache.stores.redis.lock_connection', 'lock-test'); Cache::forgetDriver('redis'); } diff --git a/tests/Integration/Cache/Redis/PhpRedisCacheLockTest.php b/tests/Integration/Cache/Redis/PhpRedisCacheLockTest.php index 978aeafb9..056d15b56 100644 --- a/tests/Integration/Cache/Redis/PhpRedisCacheLockTest.php +++ b/tests/Integration/Cache/Redis/PhpRedisCacheLockTest.php @@ -146,14 +146,15 @@ public function testRedisLockCanBeAcquiredAndReleasedWithSerializationAndCompres */ protected function configureLockConnection(array $options): void { - $baseConfig = $this->app['config']->get('database.redis.default'); + $config = $this->app->make('config'); + $baseConfig = $config->array('database.redis.default'); - $this->app['config']->set('database.redis.lock-test', array_merge($baseConfig, [ + $config->set('database.redis.lock-test', array_merge($baseConfig, [ 'options' => $options, ])); - $this->app['config']->set('cache.stores.redis.connection', 'default'); - $this->app['config']->set('cache.stores.redis.lock_connection', 'lock-test'); + $config->set('cache.stores.redis.connection', 'default'); + $config->set('cache.stores.redis.lock_connection', 'lock-test'); Cache::forgetDriver('redis'); } diff --git a/tests/Integration/Cache/Redis/RedisCacheLockTest.php b/tests/Integration/Cache/Redis/RedisCacheLockTest.php index 782c66015..104fc0ce5 100644 --- a/tests/Integration/Cache/Redis/RedisCacheLockTest.php +++ b/tests/Integration/Cache/Redis/RedisCacheLockTest.php @@ -31,7 +31,7 @@ public function testRedisLocksCanBeAcquiredAndReleased(): void public function testRedisLockCanHaveASeparateConnection(): void { - $this->app['config']->set('cache.stores.redis.lock_connection', 'default'); + $this->app->make('config')->set('cache.stores.redis.lock_connection', 'default'); $this->assertSame('default', Cache::store('redis')->lock('foo')->getConnectionName()); } diff --git a/tests/Integration/Console/CallbackSchedulingTest.php b/tests/Integration/Console/CallbackSchedulingTest.php index 0a7210981..62a23e694 100644 --- a/tests/Integration/Console/CallbackSchedulingTest.php +++ b/tests/Integration/Console/CallbackSchedulingTest.php @@ -71,9 +71,9 @@ public function testCallbacksCannotRunInBackground() ->runInBackground(); } - public function testExceptionHandlingInCallback() + public function testExceptionHandlingInCallback(): void { - $this->app['config']->set('logging.default', 'null'); + $this->app->make('config')->set('logging.default', 'null'); $event = $this->app->make(Schedule::class) ->call($this->logger('call')) diff --git a/tests/Integration/Console/CommandEventsTest.php b/tests/Integration/Console/CommandEventsTest.php index 16c404f0a..e15febc19 100644 --- a/tests/Integration/Console/CommandEventsTest.php +++ b/tests/Integration/Console/CommandEventsTest.php @@ -28,11 +28,11 @@ protected function setUp(): void } #[DataProvider('foregroundCommandEventsProvider')] - public function testCommandEventsReceiveParsedInput($callback) + public function testCommandEventsReceiveParsedInput($callback): void { - $this->app[ConsoleKernel::class]->registerCommand(new TestCommand); + $this->app->make(ConsoleKernel::class)->registerCommand(new TestCommand); - $this->app[Dispatcher::class]->listen(function (CommandStarting $event) { + $this->app->make(Dispatcher::class)->listen(function (CommandStarting $event) { $this->log[] = 'CommandStarting'; $this->log[] = $event->input->getArgument('firstname'); $this->log[] = $event->input->getArgument('lastname'); @@ -54,7 +54,7 @@ public function testCommandEventsReceiveParsedInput($callback) ], $this->log); } - public static function foregroundCommandEventsProvider() + public static function foregroundCommandEventsProvider(): iterable { yield 'Foreground with array' => [function ($testCase) { $testCase->artisan(TestCommand::class, [ @@ -69,23 +69,25 @@ public static function foregroundCommandEventsProvider() }]; } - public function testCommandEventsReceiveParsedInputViaKernelCall() + public function testCommandEventsReceiveParsedInputViaKernelCall(): void { - $this->app[Dispatcher::class]->listen(function (CommandStarting $event) { + $events = $this->app->make(Dispatcher::class); + + $events->listen(function (CommandStarting $event) { $this->log[] = 'CommandStarting'; $this->log[] = $event->input->getArgument('firstname'); $this->log[] = $event->input->getArgument('lastname'); $this->log[] = $event->input->getOption('occupation'); }); - $this->app[Dispatcher::class]->listen(function (CommandFinished $event) { + $events->listen(function (CommandFinished $event) { $this->log[] = 'CommandFinished'; $this->log[] = $event->input->getArgument('firstname'); $this->log[] = $event->input->getArgument('lastname'); $this->log[] = $event->input->getOption('occupation'); }); - $kernel = $this->app[ConsoleKernel::class]; + $kernel = $this->app->make(ConsoleKernel::class); $kernel->registerCommand(new TestCommand); $kernel->call(TestCommand::class, [ @@ -105,8 +107,7 @@ class TestCommand extends Command { protected ?string $signature = 'command-events-test-command {firstname} {lastname} {--occupation=cook}'; - public function handle() + public function handle(): void { - // ... } } diff --git a/tests/Integration/Console/ConsoleApplicationTest.php b/tests/Integration/Console/ConsoleApplicationTest.php index b84ac61dc..2aad3d1af 100644 --- a/tests/Integration/Console/ConsoleApplicationTest.php +++ b/tests/Integration/Console/ConsoleApplicationTest.php @@ -85,11 +85,11 @@ public function testArtisanWithMockCallAfterCallNow() $mock->assertExitCode(0); } - public function testArtisanInstantiateScheduleWhenNeed() + public function testArtisanInstantiateScheduleWhenNeed(): void { $this->assertFalse($this->app->resolved(Schedule::class)); - $this->app[Kernel::class]->registerCommand(new ScheduleCommand); + $this->app->make(Kernel::class)->registerCommand(new ScheduleCommand); $this->assertFalse($this->app->resolved(Schedule::class)); @@ -98,11 +98,11 @@ public function testArtisanInstantiateScheduleWhenNeed() $this->assertTrue($this->app->resolved(Schedule::class)); } - public function testArtisanQueue() + public function testArtisanQueue(): void { Queue::fake(); - $this->app[Kernel::class]->queue('foo:bar', [ + $this->app->make(Kernel::class)->queue('foo:bar', [ 'id' => 1, ]); diff --git a/tests/Integration/Console/PromptsAssertionTest.php b/tests/Integration/Console/PromptsAssertionTest.php index 95fc71b3d..8059d0c22 100644 --- a/tests/Integration/Console/PromptsAssertionTest.php +++ b/tests/Integration/Console/PromptsAssertionTest.php @@ -23,7 +23,7 @@ class PromptsAssertionTest extends TestCase { public function testAssertionForTextPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:text'; @@ -44,7 +44,7 @@ public function handle(): void public function testAssertionForPausePrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class($this) extends Command { protected ?string $signature = 'test:pause'; @@ -68,7 +68,7 @@ public function handle(): void public function testAssertionForTextareaPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:textarea'; @@ -89,7 +89,7 @@ public function handle(): void public function testAssertionForSuggestPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:suggest'; @@ -110,7 +110,7 @@ public function handle(): void public function testAssertionForPasswordPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:password'; @@ -131,7 +131,7 @@ public function handle(): void public function testAssertionForConfirmPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:confirm'; @@ -161,7 +161,7 @@ public function handle(): void public function testAssertionForSelectPromptWithAList(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:select'; @@ -185,7 +185,7 @@ public function handle(): void public function testAssertionForSelectPromptWithAnAssociativeArray(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:select'; @@ -209,7 +209,7 @@ public function handle(): void public function testAlternativeAssertionForSelectPromptWithAnAssociativeArray(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:select'; @@ -233,7 +233,7 @@ public function handle(): void public function testAssertionForRequiredMultiselectPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:multiselect'; @@ -258,7 +258,7 @@ public function handle(): void public function testAssertionForOptionalMultiselectPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:multiselect'; @@ -291,7 +291,7 @@ public function handle(): void public function testAssertionForSearchPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:search'; @@ -319,7 +319,7 @@ public function handle(): void public function testAssertionForMultisearchPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:multisearch'; @@ -356,7 +356,7 @@ public function handle(): void public function testAssertionForSelectPromptFollowedByMultisearchPrompt(): void { - $this->app[Kernel::class]->registerCommand( + $this->app->make(Kernel::class)->registerCommand( new class extends Command { protected ?string $signature = 'test:select'; diff --git a/tests/Integration/Console/PromptsValidationTest.php b/tests/Integration/Console/PromptsValidationTest.php index 829b48990..17d417c1c 100644 --- a/tests/Integration/Console/PromptsValidationTest.php +++ b/tests/Integration/Console/PromptsValidationTest.php @@ -16,10 +16,12 @@ protected function setUp(): void { parent::setUp(); - $this->app[Kernel::class]->registerCommand(new ClosureValidationCommand); - $this->app[Kernel::class]->registerCommand(new LaravelRulesCommand); - $this->app[Kernel::class]->registerCommand(new MethodMessagesCommand); - $this->app[Kernel::class]->registerCommand(new InlineMessagesCommand); + $kernel = $this->app->make(Kernel::class); + + $kernel->registerCommand(new ClosureValidationCommand); + $kernel->registerCommand(new LaravelRulesCommand); + $kernel->registerCommand(new MethodMessagesCommand); + $kernel->registerCommand(new InlineMessagesCommand); } public function testValidationForPrompts(): void diff --git a/tests/Integration/Database/DatabaseLockTest.php b/tests/Integration/Database/DatabaseLockTest.php index 8f93d7eb8..c124fbd6a 100644 --- a/tests/Integration/Database/DatabaseLockTest.php +++ b/tests/Integration/Database/DatabaseLockTest.php @@ -22,8 +22,10 @@ class DatabaseLockTest extends DatabaseTestCase { public function testLockCanHaveASeparateConnection(): void { - $this->app['config']->set('cache.stores.database.lock_connection', 'test'); - $this->app['config']->set('database.connections.test', $this->app['config']->get('database.connections.testing')); + $config = $this->app->make('config'); + + $config->set('cache.stores.database.lock_connection', 'test'); + $config->set('database.connections.test', $config->array('database.connections.testing')); $this->assertSame('test', Cache::driver('database')->lock('foo')->getConnectionName()); } diff --git a/tests/Integration/Database/EloquentStrictLoadingTest.php b/tests/Integration/Database/EloquentStrictLoadingTest.php index 91e299216..504473d63 100644 --- a/tests/Integration/Database/EloquentStrictLoadingTest.php +++ b/tests/Integration/Database/EloquentStrictLoadingTest.php @@ -71,10 +71,8 @@ public function testStrictModeDoesntThrowAnExceptionOnAttributes() $this->assertNull($models[0]->number); } - public function testStrictModeDoesntThrowAnExceptionOnEagerLoading() + public function testStrictModeDoesntThrowAnExceptionOnEagerLoading(): void { - $this->app['config']->set('database.connections.testing.zxc', false); - EloquentStrictLoadingTestModel1::create(); EloquentStrictLoadingTestModel1::create(); diff --git a/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php b/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php index e851d3a57..b5d897992 100755 --- a/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php +++ b/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Database\MariaDb; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use PDO; use PHPUnit\Framework\Attributes\RequiresOperatingSystem; use PHPUnit\Framework\Attributes\RequiresPhpExtension; @@ -12,11 +13,11 @@ #[RequiresPhpExtension('pdo_mysql')] class DatabaseEmulatePreparesMariaDbConnectionTest extends DatabaseMariaDbConnectionTest { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('database.connections.mariadb.options', [ + $app->make('config')->set('database.connections.mariadb.options', [ PDO::ATTR_EMULATE_PREPARES => true, ]); } diff --git a/tests/Integration/Database/MariaDb/DatabaseMariaDbSchemaBuilderTest.php b/tests/Integration/Database/MariaDb/DatabaseMariaDbSchemaBuilderTest.php index 674353cc5..ec8b6ff67 100644 --- a/tests/Integration/Database/MariaDb/DatabaseMariaDbSchemaBuilderTest.php +++ b/tests/Integration/Database/MariaDb/DatabaseMariaDbSchemaBuilderTest.php @@ -14,7 +14,7 @@ #[RequiresPhpExtension('pdo_mysql')] class DatabaseMariaDbSchemaBuilderTest extends MariaDbTestCase { - public function testAddCommentToTable() + public function testAddCommentToTable(): void { Schema::create('users', function (Blueprint $table) { $table->id(); @@ -22,7 +22,7 @@ public function testAddCommentToTable() }); $tableInfo = DB::table('information_schema.tables') - ->where('table_schema', $this->app['config']->get('database.connections.mariadb.database')) + ->where('table_schema', $this->app->make('config')->string('database.connections.mariadb.database')) ->where('table_name', 'users') ->select('table_comment as table_comment') ->first(); diff --git a/tests/Integration/Database/MariaDb/EscapeTest.php b/tests/Integration/Database/MariaDb/EscapeTest.php index 04b419c3b..6cbc070e3 100644 --- a/tests/Integration/Database/MariaDb/EscapeTest.php +++ b/tests/Integration/Database/MariaDb/EscapeTest.php @@ -12,62 +12,72 @@ #[RequiresPhpExtension('pdo_mysql')] class EscapeTest extends MariaDbTestCase { - public function testEscapeInt() + public function testEscapeInt(): void { - $this->assertSame('42', $this->app['db']->escape(42)); - $this->assertSame('-6', $this->app['db']->escape(-6)); + $database = $this->app->make('db'); + + $this->assertSame('42', $database->escape(42)); + $this->assertSame('-6', $database->escape(-6)); } - public function testEscapeFloat() + public function testEscapeFloat(): void { - $this->assertSame('3.14159', $this->app['db']->escape(3.14159)); - $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159)); + $database = $this->app->make('db'); + + $this->assertSame('3.14159', $database->escape(3.14159)); + $this->assertSame('-3.14159', $database->escape(-3.14159)); } - public function testEscapeBool() + public function testEscapeBool(): void { - $this->assertSame('1', $this->app['db']->escape(true)); - $this->assertSame('0', $this->app['db']->escape(false)); + $database = $this->app->make('db'); + + $this->assertSame('1', $database->escape(true)); + $this->assertSame('0', $database->escape(false)); } - public function testEscapeNull() + public function testEscapeNull(): void { - $this->assertSame('null', $this->app['db']->escape(null)); - $this->assertSame('null', $this->app['db']->escape(null, true)); + $database = $this->app->make('db'); + + $this->assertSame('null', $database->escape(null)); + $this->assertSame('null', $database->escape(null, true)); } - public function testEscapeBinary() + public function testEscapeBinary(): void { - $this->assertSame("x'dead00beef'", $this->app['db']->escape(hex2bin('dead00beef'), true)); + $this->assertSame("x'dead00beef'", $this->app->make('db')->escape(hex2bin('dead00beef'), true)); } - public function testEscapeString() + public function testEscapeString(): void { - $this->assertSame("'2147483647'", $this->app['db']->escape('2147483647')); - $this->assertSame("'true'", $this->app['db']->escape('true')); - $this->assertSame("'false'", $this->app['db']->escape('false')); - $this->assertSame("'null'", $this->app['db']->escape('null')); - $this->assertSame("'Hello\\'World'", $this->app['db']->escape("Hello'World")); + $database = $this->app->make('db'); + + $this->assertSame("'2147483647'", $database->escape('2147483647')); + $this->assertSame("'true'", $database->escape('true')); + $this->assertSame("'false'", $database->escape('false')); + $this->assertSame("'null'", $database->escape('null')); + $this->assertSame("'Hello\\'World'", $database->escape("Hello'World")); } - public function testEscapeStringInvalidUtf8() + public function testEscapeStringInvalidUtf8(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape("I am hiding an invalid \x80 utf-8 continuation byte"); + $this->app->make('db')->escape("I am hiding an invalid \x80 utf-8 continuation byte"); } - public function testEscapeStringNullByte() + public function testEscapeStringNullByte(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape("I am hiding a \00 byte"); + $this->app->make('db')->escape("I am hiding a \00 byte"); } - public function testEscapeArray() + public function testEscapeArray(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape(['a', 'b']); + $this->app->make('db')->escape(['a', 'b']); } } diff --git a/tests/Integration/Database/MigrateWithRealpathTest.php b/tests/Integration/Database/MigrateWithRealpathTest.php index 356a345a5..85aff2f08 100644 --- a/tests/Integration/Database/MigrateWithRealpathTest.php +++ b/tests/Integration/Database/MigrateWithRealpathTest.php @@ -13,7 +13,7 @@ protected function setUp(): void { parent::setUp(); - if ($this->app['config']->get('database.default') !== 'testing') { + if ($this->app->make('config')->string('database.default') !== 'testing') { $this->artisan('db:wipe', ['--drop-views' => true]); } diff --git a/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php b/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php index 07611b2fe..73797c4b1 100755 --- a/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php +++ b/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Database\MySql; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use PDO; use PHPUnit\Framework\Attributes\RequiresOperatingSystem; use PHPUnit\Framework\Attributes\RequiresPhpExtension; @@ -12,11 +13,11 @@ #[RequiresPhpExtension('pdo_mysql')] class DatabaseEmulatePreparesMySqlConnectionTest extends DatabaseMySqlConnectionTest { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('database.connections.mysql.options', [ + $app->make('config')->set('database.connections.mysql.options', [ PDO::ATTR_EMULATE_PREPARES => true, ]); } diff --git a/tests/Integration/Database/MySql/DatabaseMySqlSchemaBuilderTest.php b/tests/Integration/Database/MySql/DatabaseMySqlSchemaBuilderTest.php index d2b4dcd8c..1fe3c7d19 100644 --- a/tests/Integration/Database/MySql/DatabaseMySqlSchemaBuilderTest.php +++ b/tests/Integration/Database/MySql/DatabaseMySqlSchemaBuilderTest.php @@ -15,7 +15,7 @@ #[RequiresPhpExtension('pdo_mysql')] class DatabaseMySqlSchemaBuilderTest extends MySqlTestCase { - public function testAddCommentToTable() + public function testAddCommentToTable(): void { Schema::create('users', function (Blueprint $table) { $table->id(); @@ -23,7 +23,7 @@ public function testAddCommentToTable() }); $tableInfo = DB::table('information_schema.tables') - ->where('table_schema', $this->app['config']->get('database.connections.mysql.database')) + ->where('table_schema', $this->app->make('config')->string('database.connections.mysql.database')) ->where('table_name', 'users') ->select('table_comment as table_comment') ->first(); diff --git a/tests/Integration/Database/MySql/EscapeTest.php b/tests/Integration/Database/MySql/EscapeTest.php index b655944bd..496835cd8 100644 --- a/tests/Integration/Database/MySql/EscapeTest.php +++ b/tests/Integration/Database/MySql/EscapeTest.php @@ -12,62 +12,72 @@ #[RequiresPhpExtension('pdo_mysql')] class EscapeTest extends MySqlTestCase { - public function testEscapeInt() + public function testEscapeInt(): void { - $this->assertSame('42', $this->app['db']->escape(42)); - $this->assertSame('-6', $this->app['db']->escape(-6)); + $database = $this->app->make('db'); + + $this->assertSame('42', $database->escape(42)); + $this->assertSame('-6', $database->escape(-6)); } - public function testEscapeFloat() + public function testEscapeFloat(): void { - $this->assertSame('3.14159', $this->app['db']->escape(3.14159)); - $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159)); + $database = $this->app->make('db'); + + $this->assertSame('3.14159', $database->escape(3.14159)); + $this->assertSame('-3.14159', $database->escape(-3.14159)); } - public function testEscapeBool() + public function testEscapeBool(): void { - $this->assertSame('1', $this->app['db']->escape(true)); - $this->assertSame('0', $this->app['db']->escape(false)); + $database = $this->app->make('db'); + + $this->assertSame('1', $database->escape(true)); + $this->assertSame('0', $database->escape(false)); } - public function testEscapeNull() + public function testEscapeNull(): void { - $this->assertSame('null', $this->app['db']->escape(null)); - $this->assertSame('null', $this->app['db']->escape(null, true)); + $database = $this->app->make('db'); + + $this->assertSame('null', $database->escape(null)); + $this->assertSame('null', $database->escape(null, true)); } - public function testEscapeBinary() + public function testEscapeBinary(): void { - $this->assertSame("x'dead00beef'", $this->app['db']->escape(hex2bin('dead00beef'), true)); + $this->assertSame("x'dead00beef'", $this->app->make('db')->escape(hex2bin('dead00beef'), true)); } - public function testEscapeString() + public function testEscapeString(): void { - $this->assertSame("'2147483647'", $this->app['db']->escape('2147483647')); - $this->assertSame("'true'", $this->app['db']->escape('true')); - $this->assertSame("'false'", $this->app['db']->escape('false')); - $this->assertSame("'null'", $this->app['db']->escape('null')); - $this->assertSame("'Hello\\'World'", $this->app['db']->escape("Hello'World")); + $database = $this->app->make('db'); + + $this->assertSame("'2147483647'", $database->escape('2147483647')); + $this->assertSame("'true'", $database->escape('true')); + $this->assertSame("'false'", $database->escape('false')); + $this->assertSame("'null'", $database->escape('null')); + $this->assertSame("'Hello\\'World'", $database->escape("Hello'World")); } - public function testEscapeStringInvalidUtf8() + public function testEscapeStringInvalidUtf8(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape("I am hiding an invalid \x80 utf-8 continuation byte"); + $this->app->make('db')->escape("I am hiding an invalid \x80 utf-8 continuation byte"); } - public function testEscapeStringNullByte() + public function testEscapeStringNullByte(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape("I am hiding a \00 byte"); + $this->app->make('db')->escape("I am hiding a \00 byte"); } - public function testEscapeArray() + public function testEscapeArray(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape(['a', 'b']); + $this->app->make('db')->escape(['a', 'b']); } } diff --git a/tests/Integration/Database/Postgres/EscapeTest.php b/tests/Integration/Database/Postgres/EscapeTest.php index 120dc46c6..7ccf7981f 100644 --- a/tests/Integration/Database/Postgres/EscapeTest.php +++ b/tests/Integration/Database/Postgres/EscapeTest.php @@ -12,62 +12,72 @@ #[RequiresPhpExtension('pdo_pgsql')] class EscapeTest extends PostgresTestCase { - public function testEscapeInt() + public function testEscapeInt(): void { - $this->assertSame('42', $this->app['db']->escape(42)); - $this->assertSame('-6', $this->app['db']->escape(-6)); + $database = $this->app->make('db'); + + $this->assertSame('42', $database->escape(42)); + $this->assertSame('-6', $database->escape(-6)); } - public function testEscapeFloat() + public function testEscapeFloat(): void { - $this->assertSame('3.14159', $this->app['db']->escape(3.14159)); - $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159)); + $database = $this->app->make('db'); + + $this->assertSame('3.14159', $database->escape(3.14159)); + $this->assertSame('-3.14159', $database->escape(-3.14159)); } - public function testEscapeBool() + public function testEscapeBool(): void { - $this->assertSame('true', $this->app['db']->escape(true)); - $this->assertSame('false', $this->app['db']->escape(false)); + $database = $this->app->make('db'); + + $this->assertSame('true', $database->escape(true)); + $this->assertSame('false', $database->escape(false)); } - public function testEscapeNull() + public function testEscapeNull(): void { - $this->assertSame('null', $this->app['db']->escape(null)); - $this->assertSame('null', $this->app['db']->escape(null, true)); + $database = $this->app->make('db'); + + $this->assertSame('null', $database->escape(null)); + $this->assertSame('null', $database->escape(null, true)); } - public function testEscapeBinary() + public function testEscapeBinary(): void { - $this->assertSame("'\\xdead00beef'::bytea", $this->app['db']->escape(hex2bin('dead00beef'), true)); + $this->assertSame("'\\xdead00beef'::bytea", $this->app->make('db')->escape(hex2bin('dead00beef'), true)); } - public function testEscapeString() + public function testEscapeString(): void { - $this->assertSame("'2147483647'", $this->app['db']->escape('2147483647')); - $this->assertSame("'true'", $this->app['db']->escape('true')); - $this->assertSame("'false'", $this->app['db']->escape('false')); - $this->assertSame("'null'", $this->app['db']->escape('null')); - $this->assertSame("'Hello''World'", $this->app['db']->escape("Hello'World")); + $database = $this->app->make('db'); + + $this->assertSame("'2147483647'", $database->escape('2147483647')); + $this->assertSame("'true'", $database->escape('true')); + $this->assertSame("'false'", $database->escape('false')); + $this->assertSame("'null'", $database->escape('null')); + $this->assertSame("'Hello''World'", $database->escape("Hello'World")); } - public function testEscapeStringInvalidUtf8() + public function testEscapeStringInvalidUtf8(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape("I am hiding an invalid \x80 utf-8 continuation byte"); + $this->app->make('db')->escape("I am hiding an invalid \x80 utf-8 continuation byte"); } - public function testEscapeStringNullByte() + public function testEscapeStringNullByte(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape("I am hiding a \00 byte"); + $this->app->make('db')->escape("I am hiding a \00 byte"); } - public function testEscapeArray() + public function testEscapeArray(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape(['a', 'b']); + $this->app->make('db')->escape(['a', 'b']); } } diff --git a/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php b/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php index aaf964e2a..4faab8c6f 100644 --- a/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php +++ b/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php @@ -18,11 +18,11 @@ #[RequiresPhpExtension('pdo_pgsql')] class PostgresSchemaBuilderTest extends PostgresTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(Application $app): void { parent::defineEnvironment($app); - $app['config']->set('database.connections.pgsql.search_path', 'public,private'); + $app->make('config')->set('database.connections.pgsql.search_path', 'public,private'); } /** diff --git a/tests/Integration/Database/Postgres/PostgresStartupOptionsTest.php b/tests/Integration/Database/Postgres/PostgresStartupOptionsTest.php index c82ae3850..737ecaf90 100644 --- a/tests/Integration/Database/Postgres/PostgresStartupOptionsTest.php +++ b/tests/Integration/Database/Postgres/PostgresStartupOptionsTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Database\Postgres; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Support\Facades\DB; use PHPUnit\Framework\Attributes\RequiresOperatingSystem; use PHPUnit\Framework\Attributes\RequiresPhpExtension; @@ -28,21 +29,22 @@ #[RequiresPhpExtension('pdo_pgsql')] class PostgresStartupOptionsTest extends PostgresTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $base = $app['config']->get('database.connections.pgsql'); + $config = $app->make('config'); + $base = $config->array('database.connections.pgsql'); - $app['config']->set('database.connections.pgsql_startup_search_path', array_merge($base, [ + $config->set('database.connections.pgsql_startup_search_path', array_merge($base, [ 'search_path' => 'public,private', ])); - $app['config']->set('database.connections.pgsql_startup_isolation', array_merge($base, [ + $config->set('database.connections.pgsql_startup_isolation', array_merge($base, [ 'isolation_level' => 'read committed', ])); - $app['config']->set('database.connections.pgsql_startup_combined', array_merge($base, [ + $config->set('database.connections.pgsql_startup_combined', array_merge($base, [ 'search_path' => 'public,private', 'timezone' => 'UTC', 'isolation_level' => 'read committed', diff --git a/tests/Integration/Database/RefreshCommandTest.php b/tests/Integration/Database/RefreshCommandTest.php index c15c3176d..ab58cb0be 100644 --- a/tests/Integration/Database/RefreshCommandTest.php +++ b/tests/Integration/Database/RefreshCommandTest.php @@ -29,9 +29,9 @@ public function testRefreshWithRealpath() $this->migrateRefreshWith($options); } - private function migrateRefreshWith(array $options) + private function migrateRefreshWith(array $options): void { - if ($this->app['config']->get('database.default') !== 'testing') { + if ($this->app->make('config')->get('database.default') !== 'testing') { $this->artisan('db:wipe', ['--drop-views' => true]); } @@ -41,9 +41,9 @@ private function migrateRefreshWith(array $options) $this->artisan('migrate:refresh', $options); DB::table('members')->insert(['name' => 'foo', 'email' => 'foo@bar', 'password' => 'secret']); - $this->assertEquals(1, DB::table('members')->count()); + $this->assertSame(1, DB::table('members')->count()); $this->artisan('migrate:refresh', $options); - $this->assertEquals(0, DB::table('members')->count()); + $this->assertSame(0, DB::table('members')->count()); } } diff --git a/tests/Integration/Database/SchemaBuilderSchemaNameTest.php b/tests/Integration/Database/SchemaBuilderSchemaNameTest.php index c35a07254..fa008ce77 100644 --- a/tests/Integration/Database/SchemaBuilderSchemaNameTest.php +++ b/tests/Integration/Database/SchemaBuilderSchemaNameTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Database; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Database\Schema\Blueprint; use Hypervel\Support\Facades\DB; use Hypervel\Support\Facades\Schema; @@ -45,17 +46,18 @@ protected function destroyDatabaseMigrations(): void } } - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $connection = $app['config']->get('database.default'); + $config = $app->make('config'); + $connection = $config->string('database.default'); - $app['config']->set("database.connections.{$connection}.prefix_indexes", true); - $app['config']->set('database.connections.pgsql.search_path', 'public,my_schema'); - $app['config']->set('database.connections.without-prefix', $app['config']->get('database.connections.' . $connection)); - $app['config']->set('database.connections.with-prefix', $app['config']->get('database.connections.without-prefix')); - $app['config']->set('database.connections.with-prefix.prefix', 'example_'); + $config->set("database.connections.{$connection}.prefix_indexes", true); + $config->set('database.connections.pgsql.search_path', 'public,my_schema'); + $config->set('database.connections.without-prefix', $config->array('database.connections.' . $connection)); + $config->set('database.connections.with-prefix', $config->array('database.connections.without-prefix')); + $config->set('database.connections.with-prefix.prefix', 'example_'); } #[DataProvider('connectionProvider')] diff --git a/tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php b/tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php index 0a0bcba98..788aa23f8 100644 --- a/tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php +++ b/tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php @@ -6,6 +6,7 @@ use Closure; use Exception; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Database\QueryException; use Hypervel\Database\Schema\Blueprint; use Hypervel\Support\Facades\DB; @@ -15,9 +16,9 @@ class DatabaseSchemaBlueprintTest extends SqliteTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('database.connections.sqlite.foreign_key_constraints', false); + $app->make('config')->set('database.connections.sqlite.foreign_key_constraints', false); } protected function setUpInCoroutine(): void diff --git a/tests/Integration/Database/Sqlite/DatabaseSchemaBuilderTest.php b/tests/Integration/Database/Sqlite/DatabaseSchemaBuilderTest.php index 9640b6d52..212e73ed2 100644 --- a/tests/Integration/Database/Sqlite/DatabaseSchemaBuilderTest.php +++ b/tests/Integration/Database/Sqlite/DatabaseSchemaBuilderTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Database\Sqlite; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Database\Query\Expression; use Hypervel\Database\Schema\Blueprint; use Hypervel\Support\Facades\DB; @@ -22,9 +23,9 @@ protected function setUpInCoroutine(): void $this->artisan('migrate:install', ['--database' => 'sqlite-with-indexed-prefix']); } - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set([ + $app->make('config')->set([ 'database.connections.sqlite-with-prefix' => [ 'driver' => 'sqlite', 'database' => ':memory:', diff --git a/tests/Integration/Database/Sqlite/DatabaseSqliteConnectionTest.php b/tests/Integration/Database/Sqlite/DatabaseSqliteConnectionTest.php index 6683f7fc5..a8b760b67 100644 --- a/tests/Integration/Database/Sqlite/DatabaseSqliteConnectionTest.php +++ b/tests/Integration/Database/Sqlite/DatabaseSqliteConnectionTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Database\Sqlite; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Database\Schema\Blueprint; use Hypervel\Support\Facades\DB; use Hypervel\Support\Facades\Schema; @@ -11,13 +12,14 @@ class DatabaseSqliteConnectionTest extends SqliteTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('database.default', 'conn1'); + $config = $app->make('config'); + $config->set('database.default', 'conn1'); - $app['config']->set('database.connections.conn1', [ + $config->set('database.connections.conn1', [ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', diff --git a/tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php b/tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php index c715cf03c..c4cf4ac84 100644 --- a/tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php +++ b/tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Database\Sqlite; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Database\Schema\Blueprint; use Hypervel\Database\SQLiteConnection; use Hypervel\Filesystem\Filesystem; @@ -18,13 +19,14 @@ class DatabaseSqliteSchemaBuilderTest extends SqliteTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('database.default', 'conn1'); + $config = $app->make('config'); + $config->set('database.default', 'conn1'); - $app['config']->set('database.connections.conn1', [ + $config->set('database.connections.conn1', [ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', diff --git a/tests/Integration/Database/Sqlite/EloquentModelConnectionsTest.php b/tests/Integration/Database/Sqlite/EloquentModelConnectionsTest.php index dbc9b5214..068d3bcf4 100644 --- a/tests/Integration/Database/Sqlite/EloquentModelConnectionsTest.php +++ b/tests/Integration/Database/Sqlite/EloquentModelConnectionsTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Database\Sqlite\EloquentModelConnectionsTest; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Database\Eloquent\Model; use Hypervel\Database\Eloquent\Relations\BelongsTo; use Hypervel\Database\Eloquent\Relations\HasMany; @@ -15,17 +16,18 @@ class EloquentModelConnectionsTest extends SqliteTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('database.default', 'conn1'); + $config = $app->make('config'); + $config->set('database.default', 'conn1'); - $app['config']->set('database.connections.conn1', [ + $config->set('database.connections.conn1', [ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', ]); - $app['config']->set('database.connections.conn2', [ + $config->set('database.connections.conn2', [ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', diff --git a/tests/Integration/Database/Sqlite/EscapeTest.php b/tests/Integration/Database/Sqlite/EscapeTest.php index cb1f87db4..c989c2681 100644 --- a/tests/Integration/Database/Sqlite/EscapeTest.php +++ b/tests/Integration/Database/Sqlite/EscapeTest.php @@ -4,79 +4,91 @@ namespace Hypervel\Tests\Integration\Database\Sqlite; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use RuntimeException; class EscapeTest extends SqliteTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('database.default', 'conn1'); + $config = $app->make('config'); + $config->set('database.default', 'conn1'); - $app['config']->set('database.connections.conn1', [ + $config->set('database.connections.conn1', [ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', ]); } - public function testEscapeInt() + public function testEscapeInt(): void { - $this->assertSame('42', $this->app['db']->escape(42)); - $this->assertSame('-6', $this->app['db']->escape(-6)); + $database = $this->app->make('db'); + + $this->assertSame('42', $database->escape(42)); + $this->assertSame('-6', $database->escape(-6)); } - public function testEscapeFloat() + public function testEscapeFloat(): void { - $this->assertSame('3.14159', $this->app['db']->escape(3.14159)); - $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159)); + $database = $this->app->make('db'); + + $this->assertSame('3.14159', $database->escape(3.14159)); + $this->assertSame('-3.14159', $database->escape(-3.14159)); } - public function testEscapeBool() + public function testEscapeBool(): void { - $this->assertSame('1', $this->app['db']->escape(true)); - $this->assertSame('0', $this->app['db']->escape(false)); + $database = $this->app->make('db'); + + $this->assertSame('1', $database->escape(true)); + $this->assertSame('0', $database->escape(false)); } - public function testEscapeNull() + public function testEscapeNull(): void { - $this->assertSame('null', $this->app['db']->escape(null)); - $this->assertSame('null', $this->app['db']->escape(null, true)); + $database = $this->app->make('db'); + + $this->assertSame('null', $database->escape(null)); + $this->assertSame('null', $database->escape(null, true)); } - public function testEscapeBinary() + public function testEscapeBinary(): void { - $this->assertSame("x'dead00beef'", $this->app['db']->escape(hex2bin('dead00beef'), true)); + $this->assertSame("x'dead00beef'", $this->app->make('db')->escape(hex2bin('dead00beef'), true)); } - public function testEscapeString() + public function testEscapeString(): void { - $this->assertSame("'2147483647'", $this->app['db']->escape('2147483647')); - $this->assertSame("'true'", $this->app['db']->escape('true')); - $this->assertSame("'false'", $this->app['db']->escape('false')); - $this->assertSame("'null'", $this->app['db']->escape('null')); - $this->assertSame("'Hello''World'", $this->app['db']->escape("Hello'World")); + $database = $this->app->make('db'); + + $this->assertSame("'2147483647'", $database->escape('2147483647')); + $this->assertSame("'true'", $database->escape('true')); + $this->assertSame("'false'", $database->escape('false')); + $this->assertSame("'null'", $database->escape('null')); + $this->assertSame("'Hello''World'", $database->escape("Hello'World")); } - public function testEscapeStringInvalidUtf8() + public function testEscapeStringInvalidUtf8(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape("I am hiding an invalid \x80 utf-8 continuation byte"); + $this->app->make('db')->escape("I am hiding an invalid \x80 utf-8 continuation byte"); } - public function testEscapeStringNullByte() + public function testEscapeStringNullByte(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape("I am hiding a \00 byte"); + $this->app->make('db')->escape("I am hiding a \00 byte"); } - public function testEscapeArray() + public function testEscapeArray(): void { $this->expectException(RuntimeException::class); - $this->app['db']->escape(['a', 'b']); + $this->app->make('db')->escape(['a', 'b']); } } diff --git a/tests/Integration/Encryption/KeyGenerateCommandTest.php b/tests/Integration/Encryption/KeyGenerateCommandTest.php index cf3694208..148925ca7 100644 --- a/tests/Integration/Encryption/KeyGenerateCommandTest.php +++ b/tests/Integration/Encryption/KeyGenerateCommandTest.php @@ -43,12 +43,12 @@ protected function tearDown(): void protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('app.cipher', 'aes-128-cbc'); + $app->make('config')->set('app.cipher', 'aes-128-cbc'); } - public function testShowOptionDisplaysKeyWithoutModifyingFiles() + public function testShowOptionDisplaysKeyWithoutModifyingFiles(): void { - $this->app['config']->set('app.key', ''); + $this->app->make('config')->set('app.key', ''); file_put_contents($this->envDir . '/.env', 'APP_KEY='); $this->app->useEnvironmentPath($this->envDir); @@ -61,9 +61,10 @@ public function testShowOptionDisplaysKeyWithoutModifyingFiles() $this->assertSame('APP_KEY=', file_get_contents($this->envDir . '/.env')); } - public function testKeyIsWrittenToEnvFile() + public function testKeyIsWrittenToEnvFile(): void { - $this->app['config']->set('app.key', ''); + $config = $this->app->make('config'); + $config->set('app.key', ''); file_put_contents($this->envDir . '/.env', 'APP_KEY='); $this->app->useEnvironmentPath($this->envDir); @@ -76,12 +77,13 @@ public function testKeyIsWrittenToEnvFile() $this->assertStringStartsWith('APP_KEY=base64:', $envContents); // Config should also be updated - $this->assertStringStartsWith('base64:', $this->app['config']['app.key']); + $this->assertStringStartsWith('base64:', $config->get('app.key')); } public function testKeyIsWrittenToEnvFileWhenCurrentConfigKeyIsNull(): void { - $this->app['config']->set('app.key', null); + $config = $this->app->make('config'); + $config->set('app.key', null); file_put_contents($this->envDir . '/.env', 'APP_KEY='); $this->app->useEnvironmentPath($this->envDir); @@ -92,13 +94,13 @@ public function testKeyIsWrittenToEnvFileWhenCurrentConfigKeyIsNull(): void $envContents = file_get_contents($this->envDir . '/.env'); $this->assertStringStartsWith('APP_KEY=base64:', $envContents); - $this->assertStringStartsWith('base64:', $this->app['config']['app.key']); + $this->assertStringStartsWith('base64:', $config->get('app.key')); } - public function testForceOptionBypassesConfirmationInProduction() + public function testForceOptionBypassesConfirmationInProduction(): void { - $this->app['env'] = 'production'; - $this->app['config']->set('app.key', 'base64:' . base64_encode(str_repeat('a', 16))); + $this->app->instance('env', 'production'); + $this->app->make('config')->set('app.key', 'base64:' . base64_encode(str_repeat('a', 16))); file_put_contents($this->envDir . '/.env', 'APP_KEY=base64:' . base64_encode(str_repeat('a', 16))); $this->app->useEnvironmentPath($this->envDir); @@ -113,9 +115,9 @@ public function testForceOptionBypassesConfirmationInProduction() $this->assertStringNotContainsString(base64_encode(str_repeat('a', 16)), $envContents); } - public function testErrorWhenEnvFileHasNoAppKeyLine() + public function testErrorWhenEnvFileHasNoAppKeyLine(): void { - $this->app['config']->set('app.key', ''); + $this->app->make('config')->set('app.key', ''); file_put_contents($this->envDir . '/.env', 'APP_NAME=Hypervel'); $this->app->useEnvironmentPath($this->envDir); @@ -125,10 +127,11 @@ public function testErrorWhenEnvFileHasNoAppKeyLine() ->assertSuccessful(); } - public function testGeneratedKeyHasCorrectLengthForCipher() + public function testGeneratedKeyHasCorrectLengthForCipher(): void { - $this->app['config']->set('app.key', ''); - $this->app['config']->set('app.cipher', 'aes-256-cbc'); + $config = $this->app->make('config'); + $config->set('app.key', ''); + $config->set('app.cipher', 'aes-256-cbc'); file_put_contents($this->envDir . '/.env', 'APP_KEY='); $this->app->useEnvironmentPath($this->envDir); @@ -146,7 +149,8 @@ public function testGeneratedKeyHasCorrectLengthForCipher() public function testProhibitedCommandDoesNotGenerateOrPublishAKey(): void { - $this->app['config']->set('app.key', ''); + $config = $this->app->make('config'); + $config->set('app.key', ''); $path = $this->envDir . '/.env'; file_put_contents($path, 'APP_KEY='); KeyGenerateCommand::prohibit(); @@ -156,13 +160,14 @@ public function testProhibitedCommandDoesNotGenerateOrPublishAKey(): void ->assertSuccessful(); $this->assertSame('APP_KEY=', file_get_contents($path)); - $this->assertSame('', $this->app['config']->get('app.key')); + $this->assertSame('', $config->get('app.key')); } #[DataProvider('quotedKeyLines')] public function testExactQuotedKeyLinesAreReplaced(string $configuredKey, string $line, string $suffix): void { - $this->app['config']->set('app.key', $configuredKey); + $config = $this->app->make('config'); + $config->set('app.key', $configuredKey); $path = $this->envDir . '/.env'; file_put_contents($path, $line); @@ -171,7 +176,7 @@ public function testExactQuotedKeyLinesAreReplaced(string $configuredKey, string ->assertSuccessful(); $contents = file_get_contents($path); - $generatedKey = $this->app['config']->get('app.key'); + $generatedKey = $config->get('app.key'); $this->assertIsString($generatedKey); $this->assertStringStartsWith('base64:', $generatedKey); @@ -196,7 +201,8 @@ public static function quotedKeyLines(): array #[DataProvider('nonMatchingKeyLines')] public function testNonMatchingKeyLinesAreNotReplaced(string $line): void { - $this->app['config']->set('app.key', 'base64:current'); + $config = $this->app->make('config'); + $config->set('app.key', 'base64:current'); $path = $this->envDir . '/.env'; file_put_contents($path, $line); @@ -204,7 +210,7 @@ public function testNonMatchingKeyLinesAreNotReplaced(string $line): void ->assertSuccessful(); $this->assertSame($line, file_get_contents($path)); - $this->assertSame('base64:current', $this->app['config']->get('app.key')); + $this->assertSame('base64:current', $config->get('app.key')); } /** @@ -222,7 +228,7 @@ public static function nonMatchingKeyLines(): array public function testMissingEnvironmentFileThrowsTheFilesystemException(): void { - $this->app['config']->set('app.key', ''); + $this->app->make('config')->set('app.key', ''); $this->expectException(FileNotFoundException::class); $this->expectExceptionMessage('File does not exist at path'); @@ -232,7 +238,7 @@ public function testMissingEnvironmentFileThrowsTheFilesystemException(): void public function testEnvironmentReadFailureRemainsAFileNotFoundException(): void { - $this->app['config']->set('app.key', ''); + $this->app->make('config')->set('app.key', ''); $path = $this->envDir . '/.env'; file_put_contents($path, 'APP_KEY='); $filesystem = new FaultingKeyEnvironmentFilesystem; @@ -247,7 +253,8 @@ public function testEnvironmentReadFailureRemainsAFileNotFoundException(): void public function testEnvironmentReplacementFailureDoesNotPublishPartialState(): void { - $this->app['config']->set('app.key', ''); + $config = $this->app->make('config'); + $config->set('app.key', ''); $path = $this->envDir . '/.env'; file_put_contents($path, 'APP_KEY='); $filesystem = new FaultingKeyEnvironmentFilesystem; @@ -263,12 +270,12 @@ public function testEnvironmentReplacementFailureDoesNotPublishPartialState(): v } $this->assertSame('APP_KEY=', file_get_contents($path)); - $this->assertSame('', $this->app['config']->get('app.key')); + $this->assertSame('', $config->get('app.key')); } public function testEnvironmentFileModeIsPreservedWhenTheKeyIsReplaced(): void { - $this->app['config']->set('app.key', ''); + $this->app->make('config')->set('app.key', ''); $path = $this->envDir . '/.env'; file_put_contents($path, 'APP_KEY='); chmod($path, 0640); diff --git a/tests/Integration/Foundation/Console/RouteCacheCommandTest.php b/tests/Integration/Foundation/Console/RouteCacheCommandTest.php index e76c56879..a7dc5ba53 100644 --- a/tests/Integration/Foundation/Console/RouteCacheCommandTest.php +++ b/tests/Integration/Foundation/Console/RouteCacheCommandTest.php @@ -109,7 +109,7 @@ public function testCachedRoutesAreLoadable(): void require $this->app->getCachedRoutesPath(); - $this->assertInstanceOf(CompiledRouteCollection::class, $this->app['router']->getRoutes()); + $this->assertInstanceOf(CompiledRouteCollection::class, $this->app->make('router')->getRoutes()); } public function testNamedRoutesSurviveCache(): void @@ -125,7 +125,7 @@ public function testNamedRoutesSurviveCache(): void require $this->app->getCachedRoutesPath(); - $routes = $this->app['router']->getRoutes(); + $routes = $this->app->make('router')->getRoutes(); $this->assertSame('users', $routes->getByName('users.index')?->uri()); $this->assertSame('posts', $routes->getByName('posts.index')?->uri()); @@ -147,7 +147,7 @@ public function testRoutesWithMiddlewareDomainPrefixAndMultipleMethodsSurviveCac require $this->app->getCachedRoutesPath(); - $route = $this->app['router']->getRoutes()->getByName('api.users'); + $route = $this->app->make('router')->getRoutes()->getByName('api.users'); $this->assertNotNull($route); $this->assertSame('api.example.com', $route->getDomain()); @@ -213,7 +213,7 @@ public function testRouteCacheRebuildsFromSourceWhenApplicationBootedWithExistin require $this->app->getCachedRoutesPath(); - $route = $this->app['router']->getRoutes()->getByName('source.route'); + $route = $this->app->make('router')->getRoutes()->getByName('source.route'); $this->assertNotNull($route); $this->assertSame('beta', $route->uri()); diff --git a/tests/Integration/Foundation/ExceptionHandlerTest.php b/tests/Integration/Foundation/ExceptionHandlerTest.php index 6da2c8fb9..c9668dacf 100644 --- a/tests/Integration/Foundation/ExceptionHandlerTest.php +++ b/tests/Integration/Foundation/ExceptionHandlerTest.php @@ -47,11 +47,11 @@ public function testItRendersAuthorizationExceptions() ]); } - public function testItDoesntReportExceptionsWithShouldntReportInterface() + public function testItDoesntReportExceptionsWithShouldntReportInterface(): void { Config::set('app.debug', true); $reported = []; - $this->app[ExceptionHandler::class]->reportable(function (Throwable $e) use (&$reported) { + $this->app->make(ExceptionHandler::class)->reportable(function (Throwable $e) use (&$reported) { $reported[] = $e; }); @@ -168,12 +168,12 @@ public function testItReturns400CodeOnMalformedRequests() ]); } - public function testItHandlesMalformedErrorViewsInProduction() + public function testItHandlesMalformedErrorViewsInProduction(): void { Config::set('view.paths', [__DIR__ . '/Fixtures/MalformedErrorViews']); Config::set('app.debug', false); $reported = []; - $this->app[ExceptionHandler::class]->reportable(function (Throwable $e) use (&$reported) { + $this->app->make(ExceptionHandler::class)->reportable(function (Throwable $e) use (&$reported) { $reported[] = $e; }); @@ -189,12 +189,12 @@ public function testItHandlesMalformedErrorViewsInProduction() $response->assertStatus(404); } - public function testItHandlesMalformedErrorViewsInDevelopment() + public function testItHandlesMalformedErrorViewsInDevelopment(): void { Config::set('view.paths', [__DIR__ . '/Fixtures/MalformedErrorViews']); Config::set('app.debug', true); $reported = []; - $this->app[ExceptionHandler::class]->reportable(function (Throwable $e) use (&$reported) { + $this->app->make(ExceptionHandler::class)->reportable(function (Throwable $e) use (&$reported) { $reported[] = $e; }); @@ -210,10 +210,10 @@ public function testItHandlesMalformedErrorViewsInDevelopment() $response->assertStatus(500); } - public function testItUseCustomJsonResponseFactoryInExceptionHandler() + public function testItUseCustomJsonResponseFactoryInExceptionHandler(): void { $this->app->singleton(ResponseFactoryContract::class, function ($app) { - return new class($app['view'], $app['redirect']) extends ResponseFactory { + return new class($app->make('view'), $app->make('redirect')) extends ResponseFactory { public function json(mixed $data = [], int $status = 200, array $headers = [], int $options = 0): JsonResponse { $msg = $data['message'] ?? $data['msg'] ?? null; @@ -315,7 +315,7 @@ public function testItReportsRequestExceptions() } #[DataProvider('exitCodesProvider')] - public function testItReturnsNonZeroExitCodesForUncaughtExceptions($providers, $successful) + public function testItReturnsNonZeroExitCodesForUncaughtExceptions(array $providers, bool $successful): void { $basePath = static::applicationBasePath(); $providers = json_encode($providers); @@ -328,7 +328,7 @@ public function testItReturnsNonZeroExitCodesForUncaughtExceptions($providers, $ \$app = Hypervel\\Testbench\\Foundation\\Application::create(basePath: '{$basePath}', options: ['extra' => ['providers' => {$providers}]]); \$app->singleton('Hypervel\\Contracts\\Debug\\ExceptionHandler', 'Hypervel\\Foundation\\Exceptions\\Handler'); -\$kernel = \$app[Hypervel\\Contracts\\Console\\Kernel::class]; +\$kernel = \$app->make(Hypervel\\Contracts\\Console\\Kernel::class); return \$kernel->call('throw-exception-command'); EOF, __DIR__ . '/../../../', ['APP_RUNNING_IN_CONSOLE' => true]); diff --git a/tests/Integration/Foundation/Exceptions/RenderBladeFilesTest.php b/tests/Integration/Foundation/Exceptions/RenderBladeFilesTest.php index 080ab22c6..127ce2d99 100644 --- a/tests/Integration/Foundation/Exceptions/RenderBladeFilesTest.php +++ b/tests/Integration/Foundation/Exceptions/RenderBladeFilesTest.php @@ -52,7 +52,7 @@ public function source() $path = package_path('src/foundation/resources/exceptions/renderer/components/formatted-source.blade.php'); - $html = (string) $this->app['view']->file($path, ['frame' => $frame])->render(); + $html = (string) $this->app->make('view')->file($path, ['frame' => $frame])->render(); $this->assertStringContainsString('data-tippy-content="', $html); $this->assertStringNotContainsString('app['view']->file($path, ['queries' => $queries])->render(); + $html = (string) $this->app->make('view')->file($path, ['queries' => $queries])->render(); $this->assertStringContainsString('data-tippy-content="', $html); $this->assertMatchesRegularExpression('/<br\s*\/?>/', $html); @@ -77,7 +77,7 @@ public function testRequestHeaderTooltipRendersMultilineSafely(): void $path = package_path('src/foundation/resources/exceptions/renderer/components/request-header.blade.php'); - $html = (string) $this->app['view']->file($path, ['headers' => $headers])->render(); + $html = (string) $this->app->make('view')->file($path, ['headers' => $headers])->render(); $this->assertStringContainsString('data-tippy-content="', $html); $this->assertStringNotContainsString('app['view']->file($path, ['routing' => $routing])->render(); + $html = (string) $this->app->make('view')->file($path, ['routing' => $routing])->render(); $this->assertStringContainsString('data-tippy-content="', $html); $this->assertStringNotContainsString('app['config']; + $config = $this->app->make('config'); $config->set('logging.default', 'throw_exception'); diff --git a/tests/Integration/Foundation/FoundationServiceProvidersTest.php b/tests/Integration/Foundation/FoundationServiceProvidersTest.php index 6a840be42..0b29f4a44 100644 --- a/tests/Integration/Foundation/FoundationServiceProvidersTest.php +++ b/tests/Integration/Foundation/FoundationServiceProvidersTest.php @@ -4,20 +4,21 @@ namespace Hypervel\Tests\Integration\Foundation; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Support\ServiceProvider; use Hypervel\Testbench\TestCase; class FoundationServiceProvidersTest extends TestCase { - protected function getPackageProviders($app): array + protected function getPackageProviders(ApplicationContract $app): array { return [HeadServiceProvider::class]; } - public function testItCanBootServiceProviderRegisteredFromAnotherServiceProvider() + public function testItCanBootServiceProviderRegisteredFromAnotherServiceProvider(): void { - $this->assertTrue($this->app['tail.registered']); - $this->assertTrue($this->app['tail.booted']); + $this->assertTrue($this->app->make('tail.registered')); + $this->assertTrue($this->app->make('tail.booted')); } } @@ -37,11 +38,11 @@ class TailServiceProvider extends ServiceProvider { public function register(): void { - $this->app['tail.registered'] = true; + $this->app->instance('tail.registered', true); } public function boot(): void { - $this->app['tail.booted'] = true; + $this->app->instance('tail.booted', true); } } diff --git a/tests/Integration/Foundation/Support/Providers/RouteServiceProviderHealthTest.php b/tests/Integration/Foundation/Support/Providers/RouteServiceProviderHealthTest.php index d9e1821e6..46df7bbc4 100644 --- a/tests/Integration/Foundation/Support/Providers/RouteServiceProviderHealthTest.php +++ b/tests/Integration/Foundation/Support/Providers/RouteServiceProviderHealthTest.php @@ -30,9 +30,9 @@ protected function resolveApplication(): ApplicationContract )->create(); } - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('app.key', Str::random(32)); + $app->make('config')->set('app.key', Str::random(32)); } public function testItCanLoadHealthPage(): void diff --git a/tests/Integration/Foundation/Testing/Concerns/InteractsWithAuthenticationTest.php b/tests/Integration/Foundation/Testing/Concerns/InteractsWithAuthenticationTest.php index de8fdd3bd..cf190767a 100644 --- a/tests/Integration/Foundation/Testing/Concerns/InteractsWithAuthenticationTest.php +++ b/tests/Integration/Foundation/Testing/Concerns/InteractsWithAuthenticationTest.php @@ -8,6 +8,7 @@ use Hypervel\Context\CoroutineContext; use Hypervel\Contracts\Auth\Authenticatable as UserContract; use Hypervel\Contracts\Auth\Guard; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Database\Schema\Blueprint; use Hypervel\Foundation\Auth\User; use Hypervel\Foundation\Testing\RefreshDatabase; @@ -24,9 +25,9 @@ class InteractsWithAuthenticationTest extends TestCase { use RefreshDatabase; - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('auth.guards.api', [ + $app->make('config')->set('auth.guards.api', [ 'driver' => 'token', 'provider' => 'users', 'hash' => false, diff --git a/tests/Integration/Generators/EnumMakeCommandTest.php b/tests/Integration/Generators/EnumMakeCommandTest.php index 29b64fad1..09ce4def2 100644 --- a/tests/Integration/Generators/EnumMakeCommandTest.php +++ b/tests/Integration/Generators/EnumMakeCommandTest.php @@ -6,7 +6,7 @@ class EnumMakeCommandTest extends TestCase { - protected $files = [ + protected array $files = [ 'app/IntEnum.php', 'app/StatusEnum.php', 'app/StringEnum.php', @@ -46,12 +46,12 @@ public function testItCanGenerateEnumFileWithInt() ], 'app/IntEnum.php'); } - public function testItCanGenerateEnumFileInEnumsFolder() + public function testItCanGenerateEnumFileInEnumsFolder(): void { $enumsFolderPath = app_path('Enums'); /** @var \Hypervel\Filesystem\Filesystem $files */ - $files = $this->app['files']; + $files = $this->app->make('files'); $files->ensureDirectoryExists($enumsFolderPath); @@ -66,12 +66,12 @@ public function testItCanGenerateEnumFileInEnumsFolder() $files->deleteDirectory($enumsFolderPath); } - public function testItCanGenerateEnumFileInEnumerationsFolder() + public function testItCanGenerateEnumFileInEnumerationsFolder(): void { $enumerationsFolderPath = app_path('Enumerations'); /** @var \Hypervel\Filesystem\Filesystem $files */ - $files = $this->app['files']; + $files = $this->app->make('files'); $files->ensureDirectoryExists($enumerationsFolderPath); diff --git a/tests/Integration/Generators/InterfaceMakeCommandTest.php b/tests/Integration/Generators/InterfaceMakeCommandTest.php index 7135774f6..085f0c939 100644 --- a/tests/Integration/Generators/InterfaceMakeCommandTest.php +++ b/tests/Integration/Generators/InterfaceMakeCommandTest.php @@ -6,7 +6,7 @@ class InterfaceMakeCommandTest extends TestCase { - protected $files = [ + protected array $files = [ 'app/Gateway.php', 'app/Contracts/Gateway.php', 'app/Interfaces/Gateway.php', @@ -23,12 +23,12 @@ public function testItCanGenerateInterfaceFile() ], 'app/Gateway.php'); } - public function testItCanGenerateInterfaceFileWhenContractsFolderExists() + public function testItCanGenerateInterfaceFileWhenContractsFolderExists(): void { $interfacesFolderPath = app_path('Contracts'); /** @var \Hypervel\Filesystem\Filesystem $files */ - $files = $this->app['files']; + $files = $this->app->make('files'); $files->ensureDirectoryExists($interfacesFolderPath); @@ -43,12 +43,12 @@ public function testItCanGenerateInterfaceFileWhenContractsFolderExists() $files->deleteDirectory($interfacesFolderPath); } - public function testItCanGenerateInterfaceFileWhenInterfacesFolderExists() + public function testItCanGenerateInterfaceFileWhenInterfacesFolderExists(): void { $interfacesFolderPath = app_path('Interfaces'); /** @var \Hypervel\Filesystem\Filesystem $files */ - $files = $this->app['files']; + $files = $this->app->make('files'); $files->ensureDirectoryExists($interfacesFolderPath); diff --git a/tests/Integration/Generators/MailMakeCommandTest.php b/tests/Integration/Generators/MailMakeCommandTest.php index 57d6b6cc1..04cd6db37 100644 --- a/tests/Integration/Generators/MailMakeCommandTest.php +++ b/tests/Integration/Generators/MailMakeCommandTest.php @@ -14,7 +14,7 @@ class MailMakeCommandTest extends TestCase { - protected $files = [ + protected array $files = [ 'app/Mail/*.php', 'resources/views/foo-mail.blade.php', 'resources/views/mail/*.blade.php', @@ -60,7 +60,7 @@ public function testItCanGenerateMailFileWithMarkdownOption(): void public function testErrorsWillBeDisplayedWhenMarkdownsAlreadyExist(): void { $existingMarkdownPath = 'resources/views/existing-markdown.blade.php'; - $this->app['files'] + $this->app->make('files') ->put( $this->app->basePath($existingMarkdownPath), 'My existing markdown' @@ -102,7 +102,7 @@ public function testItCanGenerateMailFileWithViewOption(): void public function testErrorsWillBeDisplayedWhenViewsAlreadyExist(): void { $existingViewPath = 'resources/views/existing-template.blade.php'; - $this->app['files'] + $this->app->make('files') ->put( $this->app->basePath($existingViewPath), '
My existing template
' diff --git a/tests/Integration/Generators/TraitMakeCommandTest.php b/tests/Integration/Generators/TraitMakeCommandTest.php index cf9e8a84c..1494ee9f7 100644 --- a/tests/Integration/Generators/TraitMakeCommandTest.php +++ b/tests/Integration/Generators/TraitMakeCommandTest.php @@ -6,7 +6,7 @@ class TraitMakeCommandTest extends TestCase { - protected $files = [ + protected array $files = [ 'app/FooTrait.php', 'app/Traits/FooTrait.php', 'app/Concerns/FooTrait.php', @@ -23,12 +23,12 @@ public function testItCanGenerateTraitFile() ], 'app/FooTrait.php'); } - public function testItCanGenerateTraitFileWhenTraitsFolderExists() + public function testItCanGenerateTraitFileWhenTraitsFolderExists(): void { $traitsFolderPath = app_path('Traits'); /** @var \Hypervel\Filesystem\Filesystem $files */ - $files = $this->app['files']; + $files = $this->app->make('files'); $files->ensureDirectoryExists($traitsFolderPath); @@ -43,12 +43,12 @@ public function testItCanGenerateTraitFileWhenTraitsFolderExists() $files->deleteDirectory($traitsFolderPath); } - public function testItCanGenerateTraitFileWhenConcernsFolderExists() + public function testItCanGenerateTraitFileWhenConcernsFolderExists(): void { $traitsFolderPath = app_path('Concerns'); /** @var \Hypervel\Filesystem\Filesystem $files */ - $files = $this->app['files']; + $files = $this->app->make('files'); $files->ensureDirectoryExists($traitsFolderPath); diff --git a/tests/Integration/Horizon/Controller/BatchesControllerTest.php b/tests/Integration/Horizon/Controller/BatchesControllerTest.php index 3c38356ee..4cf0d5b3f 100644 --- a/tests/Integration/Horizon/Controller/BatchesControllerTest.php +++ b/tests/Integration/Horizon/Controller/BatchesControllerTest.php @@ -10,7 +10,7 @@ class BatchesControllerTest extends ControllerTestCase { - public function testBatchesCanBeSearchedByName() + public function testBatchesCanBeSearchedByName(): void { $this->setupBatchTable(); $this->seedBatches(); @@ -26,7 +26,7 @@ public function testBatchesCanBeSearchedByName() $this->assertSame('Import Users', $batches[0]->name); } - public function testBatchesCanBeSearchedByNameCaseInsensitively() + public function testBatchesCanBeSearchedByNameCaseInsensitively(): void { $this->setupBatchTable(); $this->seedBatches(); @@ -42,7 +42,7 @@ public function testBatchesCanBeSearchedByNameCaseInsensitively() $this->assertSame('Import Users', $batches[0]->name); } - public function testBatchesCanBeSearchedById() + public function testBatchesCanBeSearchedById(): void { $this->setupBatchTable(); $this->seedBatches(); @@ -58,7 +58,7 @@ public function testBatchesCanBeSearchedById() $this->assertSame('Send Emails', $batches[0]->name); } - public function testSearchEscapesLikeWildcards() + public function testSearchEscapesLikeWildcards(): void { $this->setupBatchTable(); $this->seedBatches(); @@ -88,7 +88,7 @@ public function testSearchMatchesLiteralUnderscores(): void $this->assertSame('batch_under_score', $batches[0]->id); } - public function testSearchSupportsCursorPagination() + public function testSearchSupportsCursorPagination(): void { $this->setupBatchTable(); @@ -122,9 +122,11 @@ public function testSearchAppliesAZeroCursor(): void private function setupBatchTable(): void { - $this->app['config']->set('queue.batching.database', 'testing'); - $this->app['config']->set('queue.batching.table', 'job_batches'); - $this->app['config']->set('database.connections.testing', [ + $config = $this->app->make('config'); + + $config->set('queue.batching.database', 'testing'); + $config->set('queue.batching.table', 'job_batches'); + $config->set('database.connections.testing', [ 'driver' => 'sqlite', 'database' => ':memory:', ]); diff --git a/tests/Integration/Horizon/Controller/DashboardStatsControllerTest.php b/tests/Integration/Horizon/Controller/DashboardStatsControllerTest.php index 9b4af7367..5d9425765 100644 --- a/tests/Integration/Horizon/Controller/DashboardStatsControllerTest.php +++ b/tests/Integration/Horizon/Controller/DashboardStatsControllerTest.php @@ -14,7 +14,7 @@ class DashboardStatsControllerTest extends ControllerTestCase { - public function testAllStatsAreCorrectlyReturned() + public function testAllStatsAreCorrectlyReturned(): void { // Setup supervisor data... $supervisors = m::mock(SupervisorRepository::class); @@ -53,8 +53,10 @@ public function testAllStatsAreCorrectlyReturned() ]); $this->app->instance(WaitTimeCalculator::class, $wait); - $this->app['config']->set('horizon.trim.recent_failed', 10080); - $this->app['config']->set('horizon.trim.recent', 60); + $config = $this->app->make('config'); + + $config->set('horizon.trim.recent_failed', 10080); + $config->set('horizon.trim.recent', 60); $response = $this->actingAs(new Fakes\User) ->get('/horizon/api/stats'); @@ -75,7 +77,7 @@ public function testAllStatsAreCorrectlyReturned() ]); } - public function testPausedStatusIsReflectedIfAllMasterSupervisorsArePaused() + public function testPausedStatusIsReflectedIfAllMasterSupervisorsArePaused(): void { $masters = m::mock(MasterSupervisorRepository::class); $masters->shouldReceive('all')->andReturn([ @@ -96,7 +98,7 @@ public function testPausedStatusIsReflectedIfAllMasterSupervisorsArePaused() ]); } - public function testPausedStatusIsntReflectedIfNotAllMasterSupervisorsArePaused() + public function testPausedStatusIsntReflectedIfNotAllMasterSupervisorsArePaused(): void { $masters = m::mock(MasterSupervisorRepository::class); $masters->shouldReceive('all')->andReturn([ diff --git a/tests/Integration/Horizon/ControllerTestCase.php b/tests/Integration/Horizon/ControllerTestCase.php index f3e0becdf..c73e6588c 100644 --- a/tests/Integration/Horizon/ControllerTestCase.php +++ b/tests/Integration/Horizon/ControllerTestCase.php @@ -4,16 +4,22 @@ namespace Hypervel\Tests\Integration\Horizon; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Horizon\Horizon; abstract class ControllerTestCase extends IntegrationTestCase { + protected function defineEnvironment(ApplicationContract $app): void + { + parent::defineEnvironment($app); + + $app->make('config')->set('app.key', 'base64:UTyp33UhGolgzCK5CJmT+hNHcA+dJyp3+oINtX+VoPI='); + } + protected function setUp(): void { parent::setUp(); - $this->app['config']->set('app.key', 'base64:UTyp33UhGolgzCK5CJmT+hNHcA+dJyp3+oINtX+VoPI='); - Horizon::auth(function () { return true; }); diff --git a/tests/Integration/Horizon/Feature/ClearCommandTest.php b/tests/Integration/Horizon/Feature/ClearCommandTest.php index d845ce68a..12a6fa157 100644 --- a/tests/Integration/Horizon/Feature/ClearCommandTest.php +++ b/tests/Integration/Horizon/Feature/ClearCommandTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Horizon\Feature; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ClearableQueue; use Hypervel\Contracts\Queue\Queue; use Hypervel\Horizon\Console\ClearCommand; @@ -18,15 +19,17 @@ class ClearCommandTest extends IntegrationTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('horizon.defaults', [ + $config = $app->make('config'); + + $config->set('horizon.defaults', [ 'supervisor-1' => ['connection' => 'redis'], ]); - $app['config']->set('queue.connections.redis.queue', 'default'); - $app['config']->set('queue.connections.0.queue', 'zero-default'); + $config->set('queue.connections.redis.queue', 'default'); + $config->set('queue.connections.0.queue', 'zero-default'); } #[DataProvider('queueIdentifierProvider')] diff --git a/tests/Integration/Horizon/Feature/MonitorMasterSupervisorMemoryTest.php b/tests/Integration/Horizon/Feature/MonitorMasterSupervisorMemoryTest.php index 032aa193f..e6f7e39df 100644 --- a/tests/Integration/Horizon/Feature/MonitorMasterSupervisorMemoryTest.php +++ b/tests/Integration/Horizon/Feature/MonitorMasterSupervisorMemoryTest.php @@ -16,10 +16,10 @@ protected function setUp(): void { parent::setUp(); - $this->app['env'] = 'production'; + $this->app->instance('env', 'production'); } - public function testSupervisorIsTerminatedWhenUsingTooMuchMemory() + public function testSupervisorIsTerminatedWhenUsingTooMuchMemory(): void { $monitor = new MonitorMasterSupervisorMemory; @@ -32,7 +32,7 @@ public function testSupervisorIsTerminatedWhenUsingTooMuchMemory() $monitor->handle(new MasterSupervisorLooped($master)); } - public function testSupervisorIsNotTerminatedWhenUsingLowMemory() + public function testSupervisorIsNotTerminatedWhenUsingLowMemory(): void { $monitor = new MonitorMasterSupervisorMemory; diff --git a/tests/Integration/Horizon/Feature/MonitorSupervisorMemoryTest.php b/tests/Integration/Horizon/Feature/MonitorSupervisorMemoryTest.php index e7e7c6144..1287bdc16 100644 --- a/tests/Integration/Horizon/Feature/MonitorSupervisorMemoryTest.php +++ b/tests/Integration/Horizon/Feature/MonitorSupervisorMemoryTest.php @@ -17,10 +17,10 @@ protected function setUp(): void { parent::setUp(); - $this->app['env'] = 'production'; + $this->app->instance('env', 'production'); } - public function testSupervisorIsTerminatedWhenUsingTooMuchMemory() + public function testSupervisorIsTerminatedWhenUsingTooMuchMemory(): void { $monitor = new MonitorSupervisorMemory; @@ -33,7 +33,7 @@ public function testSupervisorIsTerminatedWhenUsingTooMuchMemory() $monitor->handle(new SupervisorLooped($supervisor)); } - public function testSupervisorIsNotTerminatedWhenUsingLowMemory() + public function testSupervisorIsNotTerminatedWhenUsingLowMemory(): void { $monitor = new MonitorSupervisorMemory; diff --git a/tests/Integration/Http/Middleware/HandleCorsTest.php b/tests/Integration/Http/Middleware/HandleCorsTest.php index c21c6fe58..dde5d72b4 100644 --- a/tests/Integration/Http/Middleware/HandleCorsTest.php +++ b/tests/Integration/Http/Middleware/HandleCorsTest.php @@ -20,7 +20,7 @@ protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('cors', [ + $app->make('config')->set('cors', [ 'paths' => ['api/*'], 'supports_credentials' => false, 'allowed_origins' => ['http://localhost'], diff --git a/tests/Integration/Http/Middleware/PreventRequestForgeryServerRuntimeTest.php b/tests/Integration/Http/Middleware/PreventRequestForgeryServerRuntimeTest.php index a2b217c01..380e63ee5 100644 --- a/tests/Integration/Http/Middleware/PreventRequestForgeryServerRuntimeTest.php +++ b/tests/Integration/Http/Middleware/PreventRequestForgeryServerRuntimeTest.php @@ -55,7 +55,7 @@ public function testServerRuntimeDoesNotBypassCsrfProtectionDuringTests(): void $response = $this->get('/csrf-cookie')->assertOk(); - $sessionCookie = $this->cookieFromResponse($response->headers->getCookies(), $this->app['config']->get('session.cookie')); + $sessionCookie = $this->cookieFromResponse($response->headers->getCookies(), $this->app->make('config')->string('session.cookie')); $this->withUnencryptedCookie($sessionCookie->getName(), $sessionCookie->getValue()) ->post('/csrf-protected') @@ -67,7 +67,7 @@ public function testServerRuntimeAcceptsMatchingCsrfToken(): void $response = $this->get('/csrf-cookie')->assertOk(); $cookies = $response->headers->getCookies(); - $sessionCookie = $this->cookieFromResponse($cookies, $this->app['config']->get('session.cookie')); + $sessionCookie = $this->cookieFromResponse($cookies, $this->app->make('config')->string('session.cookie')); $xsrfCookie = $this->cookieFromResponse($cookies, 'XSRF-TOKEN'); $this->withUnencryptedCookie($sessionCookie->getName(), $sessionCookie->getValue()) diff --git a/tests/Integration/Log/ContextLoggingIntegrationTest.php b/tests/Integration/Log/ContextLoggingIntegrationTest.php index 0d6bbf2c9..e082f9ff7 100644 --- a/tests/Integration/Log/ContextLoggingIntegrationTest.php +++ b/tests/Integration/Log/ContextLoggingIntegrationTest.php @@ -15,7 +15,7 @@ class ContextLoggingIntegrationTest extends TestCase { - public function testContextIsNotUsedAsMessageParameters() + public function testContextIsNotUsedAsMessageParameters(): void { $path = $this->app->storagePath() . '/logs/hypervel.log'; file_put_contents($path, ''); @@ -30,7 +30,7 @@ public function testContextIsNotUsedAsMessageParameters() file_put_contents($path, ''); } - public function testUsesClosureForContextProcessor() + public function testUsesClosureForContextProcessor(): void { $path = $this->app->storagePath() . '/logs/hypervel.log'; file_put_contents($path, ''); @@ -60,7 +60,7 @@ public function testUsesClosureForContextProcessor() file_put_contents($path, ''); } - public function testCanRebindToSeparateClass() + public function testCanRebindToSeparateClass(): void { TestAddContextProcessor::$wasConstructed = false; @@ -82,7 +82,7 @@ public function testCanRebindToSeparateClass() file_put_contents($path, ''); } - public function testItAddsContextToLoggedExceptions() + public function testItAddsContextToLoggedExceptions(): void { $path = $this->app->storagePath() . '/logs/hypervel.log'; file_put_contents($path, ''); @@ -93,7 +93,7 @@ public function testItAddsContextToLoggedExceptions() Context::push('bar.baz', 456); Context::push('bar.baz', 789); - $this->app[ExceptionHandler::class]->report(new Exception('Whoops!')); + $this->app->make(ExceptionHandler::class)->report(new Exception('Whoops!')); $log = Str::after(file_get_contents($path), '] '); $this->assertStringEndsWith(' {"trace_id":"550e8400-e29b-41d4-a716-446655440000","foo.bar":123,"bar.baz":[456,789]}', Str::trim($log)); @@ -102,7 +102,7 @@ public function testItAddsContextToLoggedExceptions() Str::createUuidsNormally(); } - public function testClosureBoundProcessorRunsOnceOnStackedLogger() + public function testClosureBoundProcessorRunsOnceOnStackedLogger(): void { $invocationCount = 0; diff --git a/tests/Integration/Notifications/SendingMailNotificationsTest.php b/tests/Integration/Notifications/SendingMailNotificationsTest.php index 5893e3b63..1a99f336a 100644 --- a/tests/Integration/Notifications/SendingMailNotificationsTest.php +++ b/tests/Integration/Notifications/SendingMailNotificationsTest.php @@ -24,11 +24,11 @@ class SendingMailNotificationsTest extends TestCase { - public $mailFactory; + public MailFactory $mailFactory; - public $mailer; + public Mailer $mailer; - public $markdown; + public Markdown $markdown; protected function defineEnvironment(ApplicationContract $app): void { @@ -49,7 +49,7 @@ protected function defineEnvironment(ApplicationContract $app): void return $this->mailFactory; }); - $app['view']->addLocation(__DIR__ . '/Fixtures'); + $app->make('view')->addLocation(__DIR__ . '/Fixtures'); } protected function setUp(): void diff --git a/tests/Integration/Notifications/SendingMailableNotificationsTest.php b/tests/Integration/Notifications/SendingMailableNotificationsTest.php index a42ca9e78..e5236b717 100644 --- a/tests/Integration/Notifications/SendingMailableNotificationsTest.php +++ b/tests/Integration/Notifications/SendingMailableNotificationsTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Notifications; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Database\Eloquent\Model; use Hypervel\Database\Schema\Blueprint; use Hypervel\Foundation\Testing\RefreshDatabase; @@ -18,16 +19,16 @@ class SendingMailableNotificationsTest extends TestCase { use RefreshDatabase; - protected function defineEnvironment(\Hypervel\Contracts\Foundation\Application $app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('mail.default', 'array'); - $app['config']->set('mail.mailers.array', ['transport' => 'array']); + $config = $app->make('config'); - $app['config']->set('app.locale', 'en'); + $config->set('mail.default', 'array'); + $config->set('mail.mailers.array', ['transport' => 'array']); + $config->set('app.locale', 'en'); + $config->set('mail.markdown.theme', 'blank'); - $app['config']->set('mail.markdown.theme', 'blank'); - - $app['view']->addLocation(__DIR__ . '/Fixtures'); + $app->make('view')->addLocation(__DIR__ . '/Fixtures'); } protected function afterRefreshingDatabase() diff --git a/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php b/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php index 736667875..b7239b483 100644 --- a/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php +++ b/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php @@ -25,14 +25,15 @@ class SendingNotificationsWithLocaleTest extends TestCase { protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('mail.default', 'array'); - $app['config']->set('mail.mailers.array', ['transport' => 'array']); + $config = $app->make('config'); - $app['config']->set('app.locale', 'en'); + $config->set('mail.default', 'array'); + $config->set('mail.mailers.array', ['transport' => 'array']); + $config->set('app.locale', 'en'); - $app['view']->addLocation(__DIR__ . '/Fixtures'); + $app->make('view')->addLocation(__DIR__ . '/Fixtures'); - $app['translator']->setLoaded([ + $app->make('translator')->setLoaded([ '*' => [ '*' => [ 'en' => ['hi' => 'hello'], diff --git a/tests/Integration/Queue/CustomPayloadTest.php b/tests/Integration/Queue/CustomPayloadTest.php index f01afb3df..5f46294a6 100644 --- a/tests/Integration/Queue/CustomPayloadTest.php +++ b/tests/Integration/Queue/CustomPayloadTest.php @@ -21,7 +21,7 @@ protected function getPackageProviders(ApplicationContract $app): array protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('queue.default', 'sync'); + $app->make('config')->set('queue.default', 'sync'); } #[DataProvider('websites')] @@ -44,12 +44,12 @@ class QueueServiceProvider extends ServiceProvider { public function register(): void { - $this->app->bind('one.time.password', fn () => random_int(1, 10)); + $this->app->instance('one.time.password', random_int(1, 10)); Queue::createPayloadUsing(function () { $password = $this->app->make('one.time.password'); - $this->app->offsetUnset('one.time.password'); + $this->app->forgetInstance('one.time.password'); return ['password' => $password]; }); diff --git a/tests/Integration/Queue/DebouncedJobTest.php b/tests/Integration/Queue/DebouncedJobTest.php index fe541e55a..fad0537ee 100644 --- a/tests/Integration/Queue/DebouncedJobTest.php +++ b/tests/Integration/Queue/DebouncedJobTest.php @@ -11,6 +11,7 @@ use Hypervel\Container\Container; use Hypervel\Contracts\Cache\Factory as CacheFactory; use Hypervel\Contracts\Cache\Repository as Cache; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ShouldBeUnique; use Hypervel\Contracts\Queue\ShouldQueue; use Hypervel\Foundation\Bus\Dispatchable; @@ -30,12 +31,13 @@ #[WithMigration('queue')] class DebouncedJobTest extends QueueTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('cache.default', 'database'); - $app['config']->set('queue.default', 'database'); + $config = $app->make('config'); + $config->set('cache.default', 'database'); + $config->set('queue.default', 'database'); } public function testDebouncedJobDispatchesAndExecutes(): void diff --git a/tests/Integration/Queue/DeleteModelWhenMissingTest.php b/tests/Integration/Queue/DeleteModelWhenMissingTest.php index fdc226258..f25fd7980 100644 --- a/tests/Integration/Queue/DeleteModelWhenMissingTest.php +++ b/tests/Integration/Queue/DeleteModelWhenMissingTest.php @@ -5,6 +5,7 @@ namespace Hypervel\Tests\Integration\Queue\DeleteModelWhenMissingTest; use DB; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ShouldQueue; use Hypervel\Database\Eloquent\Model; use Hypervel\Database\Schema\Blueprint; @@ -20,10 +21,10 @@ #[WithMigration('queue')] class DeleteModelWhenMissingTest extends QueueTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('queue.default', 'database'); + $app->make('config')->set('queue.default', 'database'); } protected function defineDatabaseMigrationsAfterDatabaseRefreshed(): void diff --git a/tests/Integration/Queue/DeleteNotificationWhenMissingModelTest.php b/tests/Integration/Queue/DeleteNotificationWhenMissingModelTest.php index 763a465df..bbf8cc7f7 100644 --- a/tests/Integration/Queue/DeleteNotificationWhenMissingModelTest.php +++ b/tests/Integration/Queue/DeleteNotificationWhenMissingModelTest.php @@ -6,6 +6,7 @@ use DB; use Hypervel\Bus\Queueable; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ShouldQueue; use Hypervel\Database\Eloquent\Model; use Hypervel\Database\Schema\Blueprint; @@ -24,10 +25,10 @@ #[WithMigration('queue')] class DeleteNotificationWhenMissingModelTest extends QueueTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('queue.default', 'database'); + $app->make('config')->set('queue.default', 'database'); } protected function defineDatabaseMigrationsAfterDatabaseRefreshed(): void diff --git a/tests/Integration/Queue/JobChainingTest.php b/tests/Integration/Queue/JobChainingTest.php index 2c6a5d573..a42113b48 100644 --- a/tests/Integration/Queue/JobChainingTest.php +++ b/tests/Integration/Queue/JobChainingTest.php @@ -9,6 +9,7 @@ use Hypervel\Bus\Batchable; use Hypervel\Bus\PendingBatch; use Hypervel\Bus\Queueable; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ShouldQueue; use Hypervel\Foundation\Bus\Dispatchable; use Hypervel\Foundation\Bus\PendingChain; @@ -27,11 +28,11 @@ class JobChainingTest extends QueueTestCase public static bool $catchCallbackRan = false; - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set([ + $app->make('config')->set([ 'queue.connections.sync1' => ['driver' => 'sync'], 'queue.connections.sync2' => ['driver' => 'sync'], ]); diff --git a/tests/Integration/Queue/JobDispatchingTest.php b/tests/Integration/Queue/JobDispatchingTest.php index 32719cfd4..35b23b9fc 100644 --- a/tests/Integration/Queue/JobDispatchingTest.php +++ b/tests/Integration/Queue/JobDispatchingTest.php @@ -227,10 +227,12 @@ public function testQueueMayBeNullForJobQueueingAndJobQueuedEvent(): void { Config::set('queue.default', 'database'); $events = []; - $this->app['events']->listen(function (JobQueueing $e) use (&$events) { + $dispatcher = $this->app->make('events'); + + $dispatcher->listen(function (JobQueueing $e) use (&$events) { $events[] = $e; }); - $this->app['events']->listen(function (JobQueued $e) use (&$events) { + $dispatcher->listen(function (JobQueued $e) use (&$events) { $events[] = $e; }); @@ -253,7 +255,7 @@ public function testQueuedClosureCanBeNamed(): void { Config::set('queue.default', 'database'); $events = []; - $this->app['events']->listen(function (JobQueued $e) use (&$events) { + $this->app->make('events')->listen(function (JobQueued $e) use (&$events) { $events[] = $e; }); diff --git a/tests/Integration/Queue/JobEncryptionTest.php b/tests/Integration/Queue/JobEncryptionTest.php index 47c5998f4..84bbdbb07 100644 --- a/tests/Integration/Queue/JobEncryptionTest.php +++ b/tests/Integration/Queue/JobEncryptionTest.php @@ -6,6 +6,7 @@ use Hypervel\Bus\Queueable; use Hypervel\Contracts\Encryption\DecryptException; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ShouldBeEncrypted; use Hypervel\Contracts\Queue\ShouldQueue; use Hypervel\Foundation\Bus\Dispatchable; @@ -21,12 +22,13 @@ #[WithMigration('queue')] class JobEncryptionTest extends QueueTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('app.key', Str::random(32)); - $app['config']->set('queue.default', 'database'); + $config = $app->make('config'); + $config->set('app.key', Str::random(32)); + $config->set('queue.default', 'database'); } #[Override] diff --git a/tests/Integration/Queue/ModelSerializationTest.php b/tests/Integration/Queue/ModelSerializationTest.php index 4f66918a5..4c7d950fe 100644 --- a/tests/Integration/Queue/ModelSerializationTest.php +++ b/tests/Integration/Queue/ModelSerializationTest.php @@ -32,7 +32,7 @@ class ModelSerializationTest extends TestCase protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('database.connections.custom', [ + $app->make('config')->set('database.connections.custom', [ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', diff --git a/tests/Integration/Queue/QueueConnectionTest.php b/tests/Integration/Queue/QueueConnectionTest.php index d48e7f00f..ab3ee50a6 100644 --- a/tests/Integration/Queue/QueueConnectionTest.php +++ b/tests/Integration/Queue/QueueConnectionTest.php @@ -62,9 +62,9 @@ public function testJobWillGetDispatchedInsideATransactionWhenExplicitlyIndicate } } - public function testJobWontGetDispatchedInsideATransactionWhenExplicitlyIndicated() + public function testJobWontGetDispatchedInsideATransactionWhenExplicitlyIndicated(): void { - $this->app['config']->set('queue.connections.sqs.after_commit', false); + $this->app->make('config')->set('queue.connections.sqs.after_commit', false); $this->app->singleton('db.transactions', function () { $transactionManager = m::mock(DatabaseTransactionsManager::class); @@ -117,9 +117,9 @@ public function testUniqueJobWillGetDispatchedInsideATransactionWhenExplicitlyIn } } - public function testUniqueJobWontGetDispatchedInsideATransactionWhenExplicitlyIndicated() + public function testUniqueJobWontGetDispatchedInsideATransactionWhenExplicitlyIndicated(): void { - $this->app['config']->set('queue.connections.sqs.after_commit', false); + $this->app->make('config')->set('queue.connections.sqs.after_commit', false); $this->app->singleton('db.transactions', function () { $transactionManager = m::mock(DatabaseTransactionsManager::class); diff --git a/tests/Integration/Queue/QueueFakeTest.php b/tests/Integration/Queue/QueueFakeTest.php index 236be183a..9869e987b 100644 --- a/tests/Integration/Queue/QueueFakeTest.php +++ b/tests/Integration/Queue/QueueFakeTest.php @@ -15,7 +15,7 @@ class QueueFakeTest extends TestCase { protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('queue.default', 'sync'); + $app->make('config')->set('queue.default', 'sync'); } public function testFakeFor() diff --git a/tests/Integration/Queue/Redis/RedisQueueTest.php b/tests/Integration/Queue/Redis/RedisQueueTest.php index 0d1ea9096..cd8ea5a69 100644 --- a/tests/Integration/Queue/Redis/RedisQueueTest.php +++ b/tests/Integration/Queue/Redis/RedisQueueTest.php @@ -35,9 +35,9 @@ class RedisQueueTest extends TestCase private RedisQueue $queue; - public function testExpiredJobsArePopped() + public function testExpiredJobsArePopped(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); @@ -63,9 +63,9 @@ public function testExpiredJobsArePopped() $this->assertSame(3, $this->redisConnection()->zcard("{$redisKey}:reserved")); } - public function testPopProperlyPopsJobOffOfRedis() + public function testPopProperlyPopsJobOffOfRedis(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); @@ -99,7 +99,7 @@ public function testInvalidRawPayloadIsReservedWithoutMutation( ?string $expectedId, string $expectedMessage, ): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->pushRaw($payload); @@ -145,7 +145,7 @@ public static function invalidRawPayloads(): array public function testNumericStringAttemptsAreIncrementedAtomically(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->pushRaw('{"id":"job-id","job":"foo","data":[],"attempts":"2"}'); @@ -161,7 +161,7 @@ public function testNumericStringAttemptsAreIncrementedAtomically(): void public function testFractionalAttemptsReachPhpAsAnInteger(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->pushRaw('{"id":"job-id","job":"foo","data":[],"attempts":1.5}'); @@ -173,9 +173,9 @@ public function testFractionalAttemptsReachPhpAsAnInteger(): void $this->assertSame(2.5, json_decode($job->getReservedJob(), true, flags: JSON_THROW_ON_ERROR)['attempts']); } - public function testPopProperlyPopsDelayedJobOffOfRedis() + public function testPopProperlyPopsDelayedJobOffOfRedis(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); @@ -196,9 +196,9 @@ public function testPopProperlyPopsDelayedJobOffOfRedis() $this->assertEquals($job, unserialize(json_decode($reservedJob)->data->command)); } - public function testPopPopsDelayedJobOffOfRedisWhenExpireNull() + public function testPopPopsDelayedJobOffOfRedisWhenExpireNull(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default, retryAfter: null); @@ -219,9 +219,9 @@ public function testPopPopsDelayedJobOffOfRedisWhenExpireNull() $this->assertEquals($job, unserialize(json_decode($reservedJob)->data->command)); } - public function testBlockingPopProperlyPopsJobOffOfRedis() + public function testBlockingPopProperlyPopsJobOffOfRedis(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default, blockFor: 5); @@ -235,11 +235,11 @@ public function testBlockingPopProperlyPopsJobOffOfRedis() $this->assertEquals($job, unserialize(json_decode($redisJob->getReservedJob())->data->command)); } - public function testBlockingPopProperlyPopsExpiredJobs() + public function testBlockingPopProperlyPopsExpiredJobs(): void { Str::createUuidsUsing(fn () => '00000000-0000-0000-0000-000000000000'); - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default, blockFor: 5); @@ -264,9 +264,9 @@ public function testBlockingPopProperlyPopsExpiredJobs() } } - public function testNotExpireJobsWhenExpireNull() + public function testNotExpireJobsWhenExpireNull(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default, retryAfter: null); @@ -306,9 +306,9 @@ public function testNotExpireJobsWhenExpireNull() } } - public function testExpireJobsWhenExpireSet() + public function testExpireJobsWhenExpireSet(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default, retryAfter: 30); @@ -329,9 +329,9 @@ public function testExpireJobsWhenExpireSet() $this->assertEquals($job, unserialize(json_decode($reservedJob)->data->command)); } - public function testRelease() + public function testRelease(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); @@ -361,9 +361,9 @@ public function testRelease() $this->assertNull($this->queue->pop()); } - public function testReleaseInThePast() + public function testReleaseInThePast(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); @@ -377,9 +377,9 @@ public function testReleaseInThePast() $this->assertInstanceOf(RedisJob::class, $this->queue->pop()); } - public function testDelete() + public function testDelete(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); @@ -397,9 +397,9 @@ public function testDelete() $this->assertNull($this->queue->pop()); } - public function testClear() + public function testClear(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); @@ -415,9 +415,9 @@ public function testClear() $this->assertSame(0, $this->redisConnection()->llen("{$redisKey}:notify")); } - public function testSize() + public function testSize(): void { - $this->setQueue($this->app['config']->get('queue.connections.redis.queue')); + $this->setQueue($this->defaultQueueName()); $this->assertSame(0, $this->queue->size()); $this->queue->push(new RedisQueueIntegrationTestJob(1)); @@ -434,7 +434,7 @@ public function testSize() $this->assertSame(2, $this->queue->size()); } - public function testPushJobQueueingAndJobQueuedEvents() + public function testPushJobQueueingAndJobQueuedEvents(): void { $events = m::mock(Dispatcher::class); $events->shouldReceive('hasListeners')->with(JobQueueing::class)->andReturn(true)->once(); @@ -455,14 +455,14 @@ public function testPushJobQueueingAndJobQueuedEvents() $container->shouldReceive('bound')->with('events')->andReturn(true)->twice(); $container->shouldReceive('make')->with('events')->andReturn($events)->twice(); - $queue = new RedisQueue($this->app->make(RedisFactory::class), $this->app['config']->get('queue.connections.redis.queue')); + $queue = new RedisQueue($this->app->make(RedisFactory::class), $this->defaultQueueName()); $queue->setContainer($container); $queue->setConnectionName('redis'); $queue->push(new RedisQueueIntegrationTestJob(5)); } - public function testBulkJobQueuedEvent() + public function testBulkJobQueuedEvent(): void { $events = m::mock(Dispatcher::class); $events->shouldReceive('hasListeners')->with(JobQueueing::class)->andReturn(true)->times(3); @@ -474,7 +474,7 @@ public function testBulkJobQueuedEvent() $container->shouldReceive('bound')->with('events')->andReturn(true)->times(6); $container->shouldReceive('make')->with('events')->andReturn($events)->times(6); - $queue = new RedisQueue($this->app->make(RedisFactory::class), $this->app['config']->get('queue.connections.redis.queue')); + $queue = new RedisQueue($this->app->make(RedisFactory::class), $this->defaultQueueName()); $queue->setContainer($container); $queue->setConnectionName('redis'); @@ -485,7 +485,7 @@ public function testBulkJobQueuedEvent() ]); } - public function testDelayedJobsWorkWithPhpRedisSerializationEnabled() + public function testDelayedJobsWorkWithPhpRedisSerializationEnabled(): void { $connection = Redis::connection('default'); @@ -498,7 +498,7 @@ public function testDelayedJobsWorkWithPhpRedisSerializationEnabled() $client->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_PHP); try { - $this->setQueue($this->app['config']->get('queue.connections.redis.queue')); + $this->setQueue($this->defaultQueueName()); $job = new RedisQueueIntegrationTestJob(42); $this->queue->later(-10, $job); @@ -524,7 +524,7 @@ public function testDelayedJobsWorkWithPhpRedisSerializationEnabled() public function testPendingJobs(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->push(new RedisQueueIntegrationTestJob(99)); @@ -535,7 +535,7 @@ public function testPendingJobs(): void public function testDelayedJobs(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->later(60, new RedisQueueIntegrationTestJob(99)); @@ -546,7 +546,7 @@ public function testDelayedJobs(): void public function testReservedJobs(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->push(new RedisQueueIntegrationTestJob(99)); $this->queue->pop(); @@ -558,7 +558,7 @@ public function testReservedJobs(): void public function testAllPendingJobs(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->push(new RedisQueueIntegrationTestJob(1)); $this->queue->pushOn('emails', new RedisQueueIntegrationTestJob(2)); @@ -585,7 +585,7 @@ public function testAllPendingJobsReportExplicitHashTaggedNamesByTopology(): voi public function testAllDelayedJobs(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->later(60, new RedisQueueIntegrationTestJob(1)); $this->queue->laterOn('emails', 60, new RedisQueueIntegrationTestJob(2)); @@ -599,7 +599,7 @@ public function testAllDelayedJobs(): void public function testAllReservedJobs(): void { - $default = $this->app['config']->get('queue.connections.redis.queue'); + $default = $this->defaultQueueName(); $this->setQueue($default); $this->queue->push(new RedisQueueIntegrationTestJob(1)); $this->queue->pushOn('emails', new RedisQueueIntegrationTestJob(2)); @@ -642,11 +642,16 @@ private function assertInspectedJob(InspectedJob $job, ?string $queue, int $atte $this->assertInstanceOf(CarbonImmutable::class, $job->createdAt); } + private function defaultQueueName(): string + { + return $this->app->make('config')->string('queue.connections.redis.queue'); + } + private function setQueue(?string $default = null, ?string $connection = null, ?int $retryAfter = 60, ?int $blockFor = null): void { $this->queue = new RedisQueue( $this->app->make(RedisFactory::class), - $default ?? $this->app['config']->get('queue.connections.redis.queue'), + $default ?? $this->defaultQueueName(), $connection, $retryAfter, $blockFor, diff --git a/tests/Integration/Queue/UniqueJobTest.php b/tests/Integration/Queue/UniqueJobTest.php index fd11847f4..8c3df090f 100644 --- a/tests/Integration/Queue/UniqueJobTest.php +++ b/tests/Integration/Queue/UniqueJobTest.php @@ -9,6 +9,7 @@ use Hypervel\Bus\UniqueLock; use Hypervel\Container\Container; use Hypervel\Contracts\Cache\Repository as Cache; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ShouldBeUnique; use Hypervel\Contracts\Queue\ShouldBeUniqueUntilProcessing; use Hypervel\Contracts\Queue\ShouldQueue; @@ -28,12 +29,13 @@ #[WithMigration('queue')] class UniqueJobTest extends QueueTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('cache.default', 'database'); - $app['config']->set('queue.default', 'database'); + $config = $app->make('config'); + $config->set('cache.default', 'database'); + $config->set('queue.default', 'database'); } public function testUniqueJobsAreNotDispatched() diff --git a/tests/Integration/Queue/UniqueUntilProcessingJobTest.php b/tests/Integration/Queue/UniqueUntilProcessingJobTest.php index 7f2bbf5d9..c51c60cc9 100644 --- a/tests/Integration/Queue/UniqueUntilProcessingJobTest.php +++ b/tests/Integration/Queue/UniqueUntilProcessingJobTest.php @@ -5,6 +5,7 @@ namespace Hypervel\Tests\Integration\Queue\UniqueUntilProcessingJobTest; use Hypervel\Bus\Queueable; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ShouldBeUniqueUntilProcessing; use Hypervel\Contracts\Queue\ShouldQueue; use Hypervel\Foundation\Bus\Dispatchable; @@ -18,11 +19,13 @@ #[WithMigration('queue')] class UniqueUntilProcessingJobTest extends QueueTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('queue.default', 'database'); - $app['config']->set('cache.default', 'database'); + + $config = $app->make('config'); + $config->set('queue.default', 'database'); + $config->set('cache.default', 'database'); } public function testShouldBeUniqueUntilProcessingReleasesLockWhenJobIsReleasedByAMiddleware() diff --git a/tests/Integration/Queue/WorkCommandTest.php b/tests/Integration/Queue/WorkCommandTest.php index 25520ab70..4edbbbf5d 100644 --- a/tests/Integration/Queue/WorkCommandTest.php +++ b/tests/Integration/Queue/WorkCommandTest.php @@ -7,6 +7,7 @@ use Hypervel\Bus\Queueable; use Hypervel\Cache\CacheManager; use Hypervel\Cache\Repository; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ShouldQueue; use Hypervel\Database\UniqueConstraintViolationException; use Hypervel\Foundation\Bus\Dispatchable; @@ -27,11 +28,11 @@ class WorkCommandTest extends QueueTestCase { use DatabaseMigrations; - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('queue.default', 'database'); + $app->make('config')->set('queue.default', 'database'); } protected function setUp(): void @@ -87,9 +88,11 @@ public function testQueueOptionPreservesZeroAndDefaultsEmptyString(): void public function testConnectionArgumentPreservesZero(): void { - $this->app['config']->set( + $config = $this->app->make('config'); + + $config->set( 'queue.connections.0', - $this->app['config']->get('queue.connections.database'), + $config->get('queue.connections.database'), ); Queue::connection('0')->push(new FirstJob); @@ -150,7 +153,7 @@ public function testRunTimestampOutputWithDefaultAppTimezone(): void public function testRunTimestampOutputWithDifferentLogTimezone(): void { - $this->app['config']->set('queue.output_timezone', 'Europe/Helsinki'); + $this->app->make('config')->set('queue.output_timezone', 'Europe/Helsinki'); $this->travelTo(CarbonImmutable::create(2023, 1, 18, 10, 10, 11)); Queue::push(new FirstJob); @@ -164,7 +167,7 @@ public function testRunTimestampOutputWithDifferentLogTimezone(): void public function testRunTimestampOutputWithSameAppDefaultAndQueueLogDefault(): void { - $this->app['config']->set('queue.output_timezone', 'UTC'); + $this->app->make('config')->set('queue.output_timezone', 'UTC'); $this->travelTo(CarbonImmutable::create(2023, 1, 18, 10, 10, 11)); Queue::push(new FirstJob); diff --git a/tests/Integration/Routing/CompiledRouteCollectionTest.php b/tests/Integration/Routing/CompiledRouteCollectionTest.php index e1f735f57..120dbfb94 100644 --- a/tests/Integration/Routing/CompiledRouteCollectionTest.php +++ b/tests/Integration/Routing/CompiledRouteCollectionTest.php @@ -6,29 +6,25 @@ use ArrayIterator; use Hypervel\Http\Request; +use Hypervel\Routing\CompiledRouteCollection; use Hypervel\Routing\Route; use Hypervel\Routing\RouteCollection; +use Hypervel\Routing\Router; use Hypervel\Support\Arr; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class CompiledRouteCollectionTest extends RoutingTestCase { - /** - * @var \Hypervel\Routing\RouteCollection - */ - protected $routeCollection; + protected RouteCollection $routeCollection; - /** - * @var \Hypervel\Routing\Router - */ - protected $router; + protected Router $router; protected function setUp(): void { parent::setUp(); - $this->router = $this->app['router']; + $this->router = $this->app->make('router'); $this->routeCollection = new RouteCollection; } @@ -40,10 +36,7 @@ protected function tearDown(): void parent::tearDown(); } - /** - * @return \Hypervel\Routing\CompiledRouteCollection - */ - protected function collection() + protected function collection(): CompiledRouteCollection { return $this->routeCollection->toCompiledRouteCollection($this->router, $this->app); } @@ -95,7 +88,7 @@ public function testRouteCollectionCanRetrieveByAction() $this->assertSame($action, Arr::except($route->getAction(), 'as')); } - public function testCompiledAndNonCompiledUrlResolutionHasSamePrecedenceForActions() + public function testCompiledAndNonCompiledUrlResolutionHasSamePrecedenceForActions(): void { $this->router->get('/foo/{bar}', ['FooController', 'show']); $this->router->get('/foo/{bar}/{baz}', ['FooController', 'show']); @@ -104,7 +97,7 @@ public function testCompiledAndNonCompiledUrlResolutionHasSamePrecedenceForActio $this->assertSame('foo/{bar}', $this->router->getRoutes()->getByAction('FooController@show')->uri); $this->router->setCompiledRoutes($this->router->getRoutes()->compile()); - $this->assertSame('foo/{bar}', $this->app['router']->getRoutes()->getByAction('FooController@show')->uri); + $this->assertSame('foo/{bar}', $this->app->make('router')->getRoutes()->getByAction('FooController@show')->uri); } public function testCompiledAndNonCompiledUrlResolutionHasSamePrecedenceForNames() diff --git a/tests/Integration/Routing/ImplicitBackedEnumRouteBindingTest.php b/tests/Integration/Routing/ImplicitBackedEnumRouteBindingTest.php index aa0f1f4d6..801a80684 100644 --- a/tests/Integration/Routing/ImplicitBackedEnumRouteBindingTest.php +++ b/tests/Integration/Routing/ImplicitBackedEnumRouteBindingTest.php @@ -4,14 +4,15 @@ namespace Hypervel\Tests\Integration\Routing; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Support\Facades\Route; use Hypervel\Tests\Integration\Routing\Fixtures\CategoryBackedEnum; class ImplicitBackedEnumRouteBindingTest extends RoutingTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set(['app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF']); + $app->make('config')->set(['app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF']); } public function testWithRouteCachingEnabled() diff --git a/tests/Integration/Routing/PrecognitionTest.php b/tests/Integration/Routing/PrecognitionTest.php index 7cc35c92f..9ab2765b1 100644 --- a/tests/Integration/Routing/PrecognitionTest.php +++ b/tests/Integration/Routing/PrecognitionTest.php @@ -28,7 +28,7 @@ function fail() class PrecognitionTest extends RoutingTestCase { - public function testItDoesntInvokeControllerMethodByDefault() + public function testItDoesntInvokeControllerMethodByDefault(): void { Route::get('test-route', [PrecognitionTestController::class, 'methodThatFails']) ->middleware(HandlePrecognitiveRequests::class); @@ -37,12 +37,11 @@ public function testItDoesntInvokeControllerMethodByDefault() $response->assertNoContent(); $response->assertHeader('Precognition-Success', 'true'); - $this->assertTrue($this->app['ClassWasInstantiated']); + $this->assertTrue($this->app->make('ClassWasInstantiated')); } - public function testItDoesntInvokeCallableControllerByDefault() + public function testItDoesntInvokeCallableControllerByDefault(): void { - $resolved = false; Route::get('test-route', fn (ClassThatBindsOnInstantiation $foo) => fail()) ->middleware(HandlePrecognitiveRequests::class); @@ -50,7 +49,7 @@ public function testItDoesntInvokeCallableControllerByDefault() $response->assertNoContent(); $response->assertHeader('Precognition-Success', 'true'); - $this->assertTrue($this->app['ClassWasInstantiated']); + $this->assertTrue($this->app->make('ClassWasInstantiated')); } public function testItCanCheckPrecognitiveStateOnTheRequest() @@ -667,7 +666,7 @@ public function testVaryHeaderIsAppliedToNonPrecognitionResponses() $response->assertHeaderMissing('Precognition-Success'); } - public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilteringAndFormRequest() + public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilteringAndFormRequest(): void { Route::post('test-route', function (PrecognitionTestRequest $request, ClassThatBindsOnInstantiation $foo) { fail(); @@ -682,7 +681,7 @@ public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilte 'Precognition-Validate-Only' => 'optional_integer_1', ]); - $this->assertFalse($this->app['ClassWasInstantiated']); + $this->assertFalse($this->app->make('ClassWasInstantiated')); $response->assertNoContent(); $response->assertHeader('Precognition', 'true'); $response->assertHeader('Precognition-Success', 'true'); @@ -933,7 +932,7 @@ public function testItCanFilterRulesWithEscapedDotsWhenUsingControllerValidateWi $response->assertHeader('Precognition', 'true'); } - public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidationFilteringAndFormRequest() + public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidationFilteringAndFormRequest(): void { Route::post('test-route', function (PrecognitionTestRequest $request, ClassThatBindsOnInstantiation $foo) { precognitive(function ($bail) { @@ -950,7 +949,7 @@ public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidati 'Precognition' => 'true', ]); - $this->assertTrue($this->app['ClassWasInstantiated']); + $this->assertTrue($this->app->make('ClassWasInstantiated')); $response->assertOk(); $this->assertSame('expected response', $response->content()); $response->assertHeader('Precognition', 'true'); @@ -1159,11 +1158,11 @@ public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidati $response->assertHeaderMissing('Precognition-Success'); } - public function testItDoesNotSetLastUrl() + public function testItDoesNotSetLastUrl(): void { // Force the session manager to use the array driver and flush any cached driver // so the config change takes effect. - $this->app['config']->set('session.driver', 'array'); + $this->app->make('config')->set('session.driver', 'array'); $this->app->make('session')->forgetDrivers(); // Capture previousUrl inside route handlers since session() is coroutine-scoped. diff --git a/tests/Integration/Routing/UrlSigningTest.php b/tests/Integration/Routing/UrlSigningTest.php index 7e3360475..744c9fe1d 100644 --- a/tests/Integration/Routing/UrlSigningTest.php +++ b/tests/Integration/Routing/UrlSigningTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Routing\UrlSigningTest; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Routing\UrlRoutable; use Hypervel\Http\Request; use Hypervel\Routing\Exceptions\InvalidSignatureException; @@ -18,9 +19,9 @@ class UrlSigningTest extends RoutingTestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set(['app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF']); + $app->make('config')->set(['app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF']); } public function testSigningUrl() diff --git a/tests/Integration/Session/CookieSessionHandlerTest.php b/tests/Integration/Session/CookieSessionHandlerTest.php index 7a3676907..8a8b7157e 100644 --- a/tests/Integration/Session/CookieSessionHandlerTest.php +++ b/tests/Integration/Session/CookieSessionHandlerTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Session; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Support\Facades\Route; use Hypervel\Support\Str; use Hypervel\Testbench\TestCase; @@ -41,10 +42,11 @@ public function testCookieSessionInheritsRequestSecureState(): void $this->assertTrue($secureSessionValueCookie->isSecure()); } - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('app.key', Str::random(32)); - $app['config']->set('session.driver', 'cookie'); - $app['config']->set('session.expire_on_close', true); + $config = $app->make('config'); + $config->set('app.key', Str::random(32)); + $config->set('session.driver', 'cookie'); + $config->set('session.expire_on_close', true); } } diff --git a/tests/Integration/Session/SessionPersistenceTest.php b/tests/Integration/Session/SessionPersistenceTest.php index 097fce7cd..1f53e193e 100644 --- a/tests/Integration/Session/SessionPersistenceTest.php +++ b/tests/Integration/Session/SessionPersistenceTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Integration\Session; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Session\NullSessionHandler; use Hypervel\Session\TokenMismatchException; use Hypervel\Support\Facades\Exceptions; @@ -53,11 +54,12 @@ public function testPersistentSaveFailureIsRenderedWithoutRetryFailureEscaping() $this->assertSame(2, $handler->writeCount); } - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('app.key', Str::random(32)); - $app['config']->set('session.driver', 'fake-null'); - $app['config']->set('session.expire_on_close', true); + $config = $app->make('config'); + $config->set('app.key', Str::random(32)); + $config->set('session.driver', 'fake-null'); + $config->set('session.expire_on_close', true); } } diff --git a/tests/Integration/Translation/TranslatorTest.php b/tests/Integration/Translation/TranslatorTest.php index e275bcad5..e08fae880 100644 --- a/tests/Integration/Translation/TranslatorTest.php +++ b/tests/Integration/Translation/TranslatorTest.php @@ -14,58 +14,66 @@ class TranslatorTest extends TestCase { protected function defineEnvironment(ApplicationContract $app): void { - $app['translator']->addNamespace('tests', __DIR__ . '/Fixtures/lang'); - $app['translator']->addJsonPath(__DIR__ . '/Fixtures/lang'); + $translator = $app->make('translator'); + + $translator->addNamespace('tests', __DIR__ . '/Fixtures/lang'); + $translator->addJsonPath(__DIR__ . '/Fixtures/lang'); } public function testItCanGetFromLocaleForJson(): void { - $this->assertSame('30 Days', $this->app['translator']->get('30 Days')); + $translator = $this->app->make('translator'); + + $this->assertSame('30 Days', $translator->get('30 Days')); $this->app->setLocale('fr'); - $this->assertSame('30 jours', $this->app['translator']->get('30 Days')); + $this->assertSame('30 jours', $translator->get('30 Days')); } public function testItCanCheckLanguageExistsHasFromLocaleForJson(): void { - $this->assertTrue($this->app['translator']->has('1 Day')); - $this->assertTrue($this->app['translator']->hasForLocale('1 Day')); - $this->assertTrue($this->app['translator']->hasForLocale('30 Days')); + $translator = $this->app->make('translator'); + + $this->assertTrue($translator->has('1 Day')); + $this->assertTrue($translator->hasForLocale('1 Day')); + $this->assertTrue($translator->hasForLocale('30 Days')); $this->app->setLocale('fr'); - $this->assertFalse($this->app['translator']->has('1 Day')); - $this->assertFalse($this->app['translator']->hasForLocale('1 Day')); - $this->assertTrue($this->app['translator']->hasForLocale('30 Days')); + $this->assertFalse($translator->has('1 Day')); + $this->assertFalse($translator->hasForLocale('1 Day')); + $this->assertTrue($translator->hasForLocale('30 Days')); } public function testItCanCheckKeyExistsWithoutTriggeringHandleMissingKeys(): void { $missingKey = null; + $translator = $this->app->make('translator'); - $this->app['translator']->handleMissingKeysUsing(function (string $key) use (&$missingKey): void { + $translator->handleMissingKeysUsing(function (string $key) use (&$missingKey): void { $missingKey = $key; }); - $this->assertFalse($this->app['translator']->has('Foo Bar')); + $this->assertFalse($translator->has('Foo Bar')); $this->assertNull($missingKey); - $this->assertFalse($this->app['translator']->hasForLocale('Foo Bar', 'nl')); + $this->assertFalse($translator->hasForLocale('Foo Bar', 'nl')); $this->assertNull($missingKey); } public function testItCanHandleMissingKeysUsingCallback(): void { $missingKey = null; + $translator = $this->app->make('translator'); - $this->app['translator']->handleMissingKeysUsing(function (string $key) use (&$missingKey): string { + $translator->handleMissingKeysUsing(function (string $key) use (&$missingKey): string { $missingKey = $key; return 'callback key'; }); - $key = $this->app['translator']->get('some missing key'); + $key = $translator->get('some missing key'); $this->assertSame('callback key', $key); $this->assertSame('some missing key', $missingKey); @@ -74,12 +82,13 @@ public function testItCanHandleMissingKeysUsingCallback(): void public function testItCanHandleMissingKeysNoReturn(): void { $missingKey = null; + $translator = $this->app->make('translator'); - $this->app['translator']->handleMissingKeysUsing(function (string $key) use (&$missingKey): void { + $translator->handleMissingKeysUsing(function (string $key) use (&$missingKey): void { $missingKey = $key; }); - $key = $this->app['translator']->get('some missing key'); + $key = $translator->get('some missing key'); $this->assertSame('some missing key', $key); $this->assertSame('some missing key', $missingKey); @@ -88,12 +97,13 @@ public function testItCanHandleMissingKeysNoReturn(): void public function testItReturnsCorrectLocaleForMissingKeys(): void { $missingLocale = null; + $translator = $this->app->make('translator'); - $this->app['translator']->handleMissingKeysUsing(function (string $key, array $replacements, string $locale) use (&$missingLocale): void { + $translator->handleMissingKeysUsing(function (string $key, array $replacements, string $locale) use (&$missingLocale): void { $missingLocale = $locale; }); - $this->app['translator']->get('some missing key', [], 'ht'); + $translator->get('some missing key', [], 'ht'); $this->assertSame('ht', $missingLocale); } @@ -101,12 +111,13 @@ public function testItReturnsCorrectLocaleForMissingKeys(): void public function testFileValidationDoesNotAttemptToTranslateAlreadyTranslatedMessages(): void { $keysLookedUp = []; + $translator = $this->app->make('translator'); - $this->app['translator']->handleMissingKeysUsing(function (string $key) use (&$keysLookedUp): void { + $translator->handleMissingKeysUsing(function (string $key) use (&$keysLookedUp): void { $keysLookedUp[] = $key; }); - $validator = $this->app['validator']->make( + $validator = $this->app->make('validator')->make( ['file' => UploadedFile::fake()->create('file.pdf')], ['file' => [File::types(['txt'])]] ); @@ -127,7 +138,7 @@ public function testItCanHandleChoice(int $count, string $expected, ?string $loc $this->assertSame( strtr($expected, [':name' => $name, ':count' => $count]), - $this->app['translator']->choice('tests::app.greeting', $count, ['name' => $name]) + $this->app->make('translator')->choice('tests::app.greeting', $count, ['name' => $name]) ); } @@ -142,7 +153,7 @@ public function testItCanHandleChoiceWithChoiceSeparatorInReplaceString(int $cou $this->assertSame( strtr($expected, [':name' => $name, ':count' => $count]), - $this->app['translator']->choice('tests::app.greeting', $count, ['name' => $name]) + $this->app->make('translator')->choice('tests::app.greeting', $count, ['name' => $name]) ); } diff --git a/tests/Integration/View/BladeAnonymousComponentTest.php b/tests/Integration/View/BladeAnonymousComponentTest.php index 2cd81b1b9..825d87f2c 100644 --- a/tests/Integration/View/BladeAnonymousComponentTest.php +++ b/tests/Integration/View/BladeAnonymousComponentTest.php @@ -46,6 +46,6 @@ public function testAnonymousComponentsWithCustomPathsCantBeRenderedAsNormalView protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('view.paths', [__DIR__ . '/anonymous-components-templates']); + $app->make('config')->set('view.paths', [__DIR__ . '/anonymous-components-templates']); } } diff --git a/tests/Integration/View/BladeTest.php b/tests/Integration/View/BladeTest.php index c0d0ef113..d4e67fcda 100644 --- a/tests/Integration/View/BladeTest.php +++ b/tests/Integration/View/BladeTest.php @@ -250,7 +250,7 @@ public function testViewCacheCommandDeduplicatesPathsBeforeCompiling(): void #[Override] protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('view.paths', [__DIR__ . '/templates']); + $app->make('config')->set('view.paths', [__DIR__ . '/templates']); } } diff --git a/tests/Integration/View/RenderableViewExceptionTest.php b/tests/Integration/View/RenderableViewExceptionTest.php index c2eb7e13e..812667844 100644 --- a/tests/Integration/View/RenderableViewExceptionTest.php +++ b/tests/Integration/View/RenderableViewExceptionTest.php @@ -27,7 +27,7 @@ public function testRenderMethodOfExceptionThrownInViewGetsHandled(): void protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('view.paths', [__DIR__ . '/templates']); + $app->make('config')->set('view.paths', [__DIR__ . '/templates']); } } diff --git a/tests/Log/ContextQueueTest.php b/tests/Log/ContextQueueTest.php index 4ae5d36bb..15d8536a8 100644 --- a/tests/Log/ContextQueueTest.php +++ b/tests/Log/ContextQueueTest.php @@ -193,7 +193,7 @@ public function testContextIsHydratedWhenJobProcesses(): void $job->shouldReceive('payload')->andReturn($payload); $event = new JobProcessing('sync', $job); - $this->app['events']->dispatch($event); + $this->app->make('events')->dispatch($event); // Context should now be hydrated $this->assertSame('abc-123', Repository::getInstance()->get('trace_id')); @@ -206,7 +206,7 @@ public function testHydrateSkipsWhenPayloadHasNoContext(): void $job->shouldReceive('payload')->andReturn(['job' => 'SomeJob']); $event = new JobProcessing('sync', $job); - $this->app['events']->dispatch($event); + $this->app->make('events')->dispatch($event); // No context Repository should have been allocated $this->assertFalse(Repository::hasInstance()); @@ -221,7 +221,7 @@ public function testPayloadWithoutContextFlushesAnExistingRepository(): void $job = m::mock(\Hypervel\Contracts\Queue\Job::class); $job->shouldReceive('payload')->andReturn(['job' => 'SomeJob']); - $this->app['events']->dispatch(new JobProcessing('sync', $job)); + $this->app->make('events')->dispatch(new JobProcessing('sync', $job)); $this->assertSame($repository, Repository::getInstance()); $this->assertSame([], $repository->all()); @@ -266,7 +266,7 @@ public function testHydratedHookFiresWhenJobProcesses(): void $job = m::mock(\Hypervel\Contracts\Queue\Job::class); $job->shouldReceive('payload')->andReturn($payload); - $this->app['events']->dispatch(new JobProcessing('sync', $job)); + $this->app->make('events')->dispatch(new JobProcessing('sync', $job)); $this->assertTrue($called); } @@ -311,7 +311,7 @@ public function testRoundTripPreservesVariousDataTypes(): void // Hydrate from the payload $job = m::mock(\Hypervel\Contracts\Queue\Job::class); $job->shouldReceive('payload')->andReturn($payload); - $this->app['events']->dispatch(new JobProcessing('sync', $job)); + $this->app->make('events')->dispatch(new JobProcessing('sync', $job)); // Verify all types survived the round trip $this->assertSame('hello', Repository::getInstance()->get('string')); diff --git a/tests/Log/LogManagerTest.php b/tests/Log/LogManagerTest.php index 852125348..cb1162ccd 100644 --- a/tests/Log/LogManagerTest.php +++ b/tests/Log/LogManagerTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Log; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Log\Context\ResolvedContextLogProcessor; use Hypervel\Log\Handlers\FingersCrossedHandler as HypervelFingersCrossedHandler; use Hypervel\Log\Handlers\RotatingFileHandler as HypervelRotatingFileHandler; @@ -34,7 +35,7 @@ class LogManagerTest extends TestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { $app->make('config')->set('logging.channels.single', [ 'driver' => 'single', @@ -340,7 +341,7 @@ public function testDailyDriverUsesCoroutineSafeRotatingHandler(): void $this->assertSame(HypervelRotatingFileHandler::class, get_class($handler)); } - public function testItUtilisesTheNullDriverDuringTestsWhenNullDriverUsed() + public function testItUtilizesTheNullDriverDuringTestsWhenNullDriverUsed(): void { $manager = new class($this->app) extends LogManager { protected function createEmergencyLogger(): LoggerInterface @@ -349,7 +350,7 @@ protected function createEmergencyLogger(): LoggerInterface } }; - $this->app['env'] = 'testing'; + $this->app->instance('env', 'testing'); $config = $this->app->make('config'); $config->set('logging.default', null); $config->set('logging.channels.null', [ @@ -369,7 +370,7 @@ protected function createEmergencyLogger(): LoggerInterface $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Emergency logger was created.'); - $this->app['env'] = 'production'; + $this->app->instance('env', 'production'); $manager->info('message'); } diff --git a/tests/Queue/QueueCommandIdentifierTest.php b/tests/Queue/QueueCommandIdentifierTest.php index b8b07ebb0..ef958bd03 100644 --- a/tests/Queue/QueueCommandIdentifierTest.php +++ b/tests/Queue/QueueCommandIdentifierTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Queue; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Contracts\Queue\ClearableQueue; use Hypervel\Contracts\Queue\Queue; use Hypervel\Queue\Console\ClearCommand; @@ -18,11 +19,13 @@ class QueueCommandIdentifierTest extends TestCase { - protected function defineEnvironment($app): void + protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('queue.default', 'redis'); - $app['config']->set('queue.connections.redis.queue', 'default'); - $app['config']->set('queue.connections.0.queue', 'zero-default'); + $config = $app->make('config'); + + $config->set('queue.default', 'redis'); + $config->set('queue.connections.redis.queue', 'default'); + $config->set('queue.connections.0.queue', 'zero-default'); } #[DataProvider('queueIdentifierProvider')] @@ -59,7 +62,7 @@ public function testListenCommandPreservesZeroAndDefaultsEmptyIdentifiers( string $expectedConnection, string $expectedQueue, ): void { - $this->app['config']->set("queue.connections.{$expectedConnection}.queue", $expectedQueue); + $this->app->make('config')->set("queue.connections.{$expectedConnection}.queue", $expectedQueue); $listener = m::mock(Listener::class); $listener->shouldReceive('setOutputHandler')->once(); diff --git a/tests/Reverb/EventDispatcherTest.php b/tests/Reverb/EventDispatcherTest.php index cdda7a699..94a2c74c1 100644 --- a/tests/Reverb/EventDispatcherTest.php +++ b/tests/Reverb/EventDispatcherTest.php @@ -206,7 +206,7 @@ public function testCacheMissLockClearsOnVacateAndFiresOnRecreation(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['cache_miss'], 'disconnect_smoothing_ms' => 0, diff --git a/tests/Reverb/Protocols/Pusher/Channels/ChannelTest.php b/tests/Reverb/Protocols/Pusher/Channels/ChannelTest.php index 5eec71778..e7b81cc55 100644 --- a/tests/Reverb/Protocols/Pusher/Channels/ChannelTest.php +++ b/tests/Reverb/Protocols/Pusher/Channels/ChannelTest.php @@ -282,7 +282,7 @@ public function testSubscribeFiresSubscriptionCountWebhook(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], 'subscription_count' => true, @@ -303,7 +303,7 @@ public function testUnsubscribeFiresSubscriptionCountWebhook(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], 'subscription_count' => true, @@ -330,7 +330,7 @@ public function testSubscriptionCountNotFiredWhenOptInIsFalse(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], // subscription_count not set — defaults to false @@ -347,7 +347,7 @@ public function testSubscriptionCountNotFiredForPresenceChannels(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], 'subscription_count' => true, @@ -364,7 +364,7 @@ public function testSubscriptionCountNotFiredForPresenceCacheChannels(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], 'subscription_count' => true, @@ -381,7 +381,7 @@ public function testSubscriptionCountFiredForPrivateChannels(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], 'subscription_count' => true, @@ -398,7 +398,7 @@ public function testSubscriptionCountFiredForCacheChannels(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], 'subscription_count' => true, @@ -417,7 +417,7 @@ public function testDisconnectDefersChannelVacatedWebhook(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['channel_vacated'], 'disconnect_smoothing_ms' => 3000, @@ -430,7 +430,7 @@ public function testDisconnectDefersChannelVacatedWebhook(): void $server = $this->app->make(Server::class); $server->close($connection); - // Webhook should NOT fire immediately — it's deferred + // Webhook should not fire immediately — it's deferred Queue::assertNotPushed(WebhookDeliveryJob::class, function (WebhookDeliveryJob $job) { return $job->payload->events[0]['name'] === 'channel_vacated'; }); @@ -440,7 +440,7 @@ public function testExplicitUnsubscribeFiresChannelVacatedImmediately(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['channel_vacated'], 'disconnect_smoothing_ms' => 3000, @@ -465,7 +465,7 @@ public function testReconnectWithinSmoothingWindowSuppressesChannelOccupied(): v { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['channel_occupied', 'channel_vacated'], 'disconnect_smoothing_ms' => 3000, @@ -491,7 +491,7 @@ public function testNormalSubscribeFiresChannelOccupied(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['channel_occupied'], 'disconnect_smoothing_ms' => 3000, @@ -509,7 +509,7 @@ public function testCrossWorkerSmoothingMarkerSuppressesChannelOccupied(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['channel_occupied'], 'disconnect_smoothing_ms' => 3000, @@ -534,7 +534,7 @@ public function testConsumedMarkerDoesNotSuppressSubsequentLegitimateOccupied(): { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['channel_occupied', 'channel_vacated'], 'disconnect_smoothing_ms' => 3000, @@ -568,7 +568,7 @@ public function testSubscriptionCountThrottledAbove100Subscribers(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], 'subscription_count' => true, @@ -603,7 +603,7 @@ public function testSubscriptionCountFiresAbove100WhenLockAcquired(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => [], 'subscription_count' => true, diff --git a/tests/Reverb/Protocols/Pusher/Channels/PresenceChannelTest.php b/tests/Reverb/Protocols/Pusher/Channels/PresenceChannelTest.php index 01d432d31..a7b9b2b4a 100644 --- a/tests/Reverb/Protocols/Pusher/Channels/PresenceChannelTest.php +++ b/tests/Reverb/Protocols/Pusher/Channels/PresenceChannelTest.php @@ -180,7 +180,7 @@ public function testSubscriptionAndUnsubscriptionPreserveZeroUserId(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['member_added', 'member_removed'], 'disconnect_smoothing_ms' => 0, @@ -232,7 +232,7 @@ public function testEnsuresTheMemberAddedEventIsOnlyFiredOnce(): void $channel->subscribe($connectionOne->connection(), static::validAuth($connectionOne->id(), 'presence-test-channel', $data = json_encode($connectionOne->data())), $data); $channel->subscribe($connectionTwo->connection(), static::validAuth($connectionTwo->id(), 'presence-test-channel', $data = json_encode($connectionTwo->data())), $data); - // Second subscribe for same user_id should NOT trigger member_added broadcast + // Second subscribe for same user_id should not trigger member_added broadcast $connectionOne->connection()->assertNothingReceived(); } @@ -265,7 +265,7 @@ public function testDisconnectDefersMemberRemovedWebhook(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['member_removed'], 'disconnect_smoothing_ms' => 3000, @@ -289,7 +289,7 @@ public function testDisconnectDefersMemberRemovedWebhook(): void $this->connection->markDisconnecting(); $channel->unsubscribe($this->connection); - // Webhook should NOT fire immediately — it's deferred + // Webhook should not fire immediately — it's deferred Queue::assertNotPushed(WebhookDeliveryJob::class, function (WebhookDeliveryJob $job) { return $job->payload->events[0]['name'] === 'member_removed'; }); @@ -299,7 +299,7 @@ public function testExplicitUnsubscribeFiresMemberRemovedImmediately(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['member_removed'], 'disconnect_smoothing_ms' => 3000, @@ -334,7 +334,7 @@ public function testReconnectWithinSmoothingWindowSuppressesMemberAddedWebhook() { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['member_added', 'member_removed'], 'disconnect_smoothing_ms' => 3000, @@ -349,7 +349,6 @@ public function testReconnectWithinSmoothingWindowSuppressesMemberAddedWebhook() $data ); - // Set up mock for unsubscribe's find() call // Simulate disconnect $this->connection->markDisconnecting(); $channel->unsubscribe($this->connection); @@ -377,7 +376,7 @@ public function testReconnectStillSendsInternalMemberAddedEvent(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['member_added', 'member_removed'], 'disconnect_smoothing_ms' => 3000, @@ -426,7 +425,7 @@ public function testCrossWorkerSmoothingMarkerSuppressesMemberAdded(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['member_added'], 'disconnect_smoothing_ms' => 3000, @@ -455,7 +454,7 @@ public function testConsumedMemberMarkerDoesNotSuppressSubsequentLegitimateAdd() { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['member_added', 'member_removed'], 'disconnect_smoothing_ms' => 3000, diff --git a/tests/Reverb/Protocols/Pusher/ClientEventTest.php b/tests/Reverb/Protocols/Pusher/ClientEventTest.php index 20d5a27ef..8032b9574 100644 --- a/tests/Reverb/Protocols/Pusher/ClientEventTest.php +++ b/tests/Reverb/Protocols/Pusher/ClientEventTest.php @@ -61,7 +61,7 @@ public function testClientMessagePreservesZeroUserIdInBroadcastAndWebhook(): voi { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['client_event'], ]); @@ -133,7 +133,7 @@ public function testRejectClientEventOnPublicChannelInMembersMode(): void public function testAllowsClientEventOnPublicChannelInAllMode(): void { - $this->app['config']->set('reverb.apps.apps.0.accept_client_events_from', 'all'); + config()->set('reverb.apps.apps.0.accept_client_events_from', 'all'); $this->channels()->findOrCreate('test-channel'); $this->channelConnectionManager->shouldReceive('all') @@ -161,7 +161,7 @@ public function testRejectClientEventOnPublicChannelDoesNotProduceWebhook(): voi { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['client_event'], ]); @@ -215,7 +215,7 @@ public function testDoesNotForwardUnauthenticatedClientMessageWhenInMembersMode( public function testDoesNotForwardClientMessageWhenSetToNone(): void { - $this->app['config']->set('reverb.apps.apps.0.accept_client_events_from', 'none'); + config()->set('reverb.apps.apps.0.accept_client_events_from', 'none'); $this->channels()->findOrCreate('private-test-channel'); $connectionOne = collect(static::factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => '1']))->first(); @@ -247,7 +247,7 @@ public function testDoesNotForwardClientMessageWhenSetToNone(): void public function testForwardsAClientMessageForUnauthenticatedClientWhenSetToAll(): void { - $this->app['config']->set('reverb.apps.apps.0.accept_client_events_from', 'all'); + config()->set('reverb.apps.apps.0.accept_client_events_from', 'all'); $connection = new FakeConnection; $this->channels()->findOrCreate('test-channel'); @@ -298,8 +298,8 @@ public function testWebhookIncludesUserIdForPresenceChannelInAllMode(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.accept_client_events_from', 'all'); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.accept_client_events_from', 'all'); + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['client_event'], ]); diff --git a/tests/Reverb/Protocols/Pusher/EventHandlerTest.php b/tests/Reverb/Protocols/Pusher/EventHandlerTest.php index bfd81ba75..c1e4ef0e8 100644 --- a/tests/Reverb/Protocols/Pusher/EventHandlerTest.php +++ b/tests/Reverb/Protocols/Pusher/EventHandlerTest.php @@ -319,7 +319,7 @@ public function testCacheMissFiresWebhook(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['cache_miss'], ]); @@ -338,7 +338,7 @@ public function testCacheHitDoesNotFireWebhook(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['cache_miss'], ]); @@ -366,7 +366,7 @@ public function testCacheMissWebhookIsDeduplicated(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['cache_miss'], ]); @@ -392,9 +392,9 @@ public function testCacheMissWebhookRespectsEventFilter(): void { Queue::fake(); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', - 'events' => ['channel_occupied'], // cache_miss NOT in the list + 'events' => ['channel_occupied'], // cache_miss is not in the list ]); $this->pusher->subscribe($this->connection, 'cache-test-channel'); @@ -407,11 +407,11 @@ public function testCacheMissWebhookRespectsEventFilter(): void public function testCacheMissWithNoWebhooksDoesNotTouchLock(): void { // Default config — no webhook URL configured - $sharedState = $this->app->make(\Hypervel\Reverb\Servers\Hypervel\Contracts\SharedState::class); + $sharedState = $this->app->make(SharedState::class); $this->pusher->subscribe($this->connection, 'cache-test-channel'); - // The lock should NOT have been acquired since hasWebhooks() is false. + // The lock should not have been acquired since hasWebhooks() is false. // Verify by acquiring it now — if it was already held, this would fail. $this->assertTrue( $sharedState->tryCacheMissLock($this->connection->app()->id(), 'cache-test-channel') diff --git a/tests/Reverb/Protocols/Pusher/Http/Controllers/EventsControllerTest.php b/tests/Reverb/Protocols/Pusher/Http/Controllers/EventsControllerTest.php index 9a3ec764f..5cbf022c2 100644 --- a/tests/Reverb/Protocols/Pusher/Http/Controllers/EventsControllerTest.php +++ b/tests/Reverb/Protocols/Pusher/Http/Controllers/EventsControllerTest.php @@ -88,7 +88,7 @@ public function testCanIgnoreASubscriber(): void $connection->assertReceivedCount(1); - // Second request — exclude this socket, connection should NOT receive + // Second request — exclude this socket, connection should not receive $connection->resetReceived(); $this->signedPostRequest('events', [ 'name' => 'NewEvent', @@ -254,7 +254,7 @@ public function testCanVerifySignatureWhenUsingACustomServerPath(): void $body = json_encode($data); $timestamp = time(); - // Build the signature WITHOUT the path prefix (as the Pusher PHP client does) + // Build the signature without the path prefix (as the Pusher PHP client does) $query = "auth_key={$key}&auth_timestamp={$timestamp}&auth_version=1.0"; $params = explode('&', $query); sort($params); @@ -264,7 +264,7 @@ public function testCanVerifySignatureWhenUsingACustomServerPath(): void $signatureString = "POST\n/apps/{$appId}/events\n{$query}"; $signature = hash_hmac('sha256', $signatureString, $secret); - // Send the request TO the prefixed URL + // Send the request to the prefixed URL $response = $this->reverbCall('POST', "/ws/apps/{$appId}/events?{$query}&auth_signature={$signature}", [ 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => (string) strlen($body), @@ -278,7 +278,7 @@ public function testCanVerifySignatureWhenUsingACustomServerPath(): void */ protected function withPathPrefix(ApplicationContract $app): void { - $app['config']->set('reverb.servers.reverb.path', '/ws'); + $app->make('config')->set('reverb.servers.reverb.path', '/ws'); } public function testReturnsEmptyObjectWhenNoInfoRequested(): void diff --git a/tests/Reverb/Protocols/Pusher/ServerTest.php b/tests/Reverb/Protocols/Pusher/ServerTest.php index 1dbfe8854..2505eb34a 100644 --- a/tests/Reverb/Protocols/Pusher/ServerTest.php +++ b/tests/Reverb/Protocols/Pusher/ServerTest.php @@ -7,6 +7,7 @@ use Hypervel\Contracts\Debug\ExceptionHandler; use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Reverb\Connection; +use Hypervel\Reverb\Contracts\ApplicationProvider; use Hypervel\Reverb\Contracts\WebSocketConnection; use Hypervel\Reverb\Events\ConnectionClosed; use Hypervel\Reverb\Events\ConnectionEstablished; @@ -386,7 +387,7 @@ public function testUnsubscribesAUserFromAPresenceChannelOnDisconnection(): void #[DataProvider('invalidOriginProvider')] public function testRejectsAConnectionFromAnInvalidOrigin(string $origin, array $allowedOrigins): void { - $this->app['config']->set('reverb.apps.apps.0.allowed_origins', $allowedOrigins); + config()->set('reverb.apps.apps.0.allowed_origins', $allowedOrigins); $this->server->open($connection = new FakeConnection(origin: $origin)); $this->assertFalse($connection->isEstablished()); @@ -410,11 +411,11 @@ public static function invalidOriginProvider(): array public function testRejectsAConnectionWithoutAnOrigin(): void { - $this->app['config']->set('reverb.apps.apps.0.allowed_origins', ['localhost']); + config()->set('reverb.apps.apps.0.allowed_origins', ['localhost']); $webSocket = m::mock(WebSocketConnection::class); $webSocket->shouldReceive('send')->once(); - $application = $this->app->make(\Hypervel\Reverb\Contracts\ApplicationProvider::class) + $application = $this->app->make(ApplicationProvider::class) ->findByKey('reverb-key'); $connection = new Connection($webSocket, $application, null); @@ -426,7 +427,7 @@ public function testRejectsAConnectionWithoutAnOrigin(): void #[DataProvider('validOriginProvider')] public function testAcceptsAConnectionFromAValidOrigin(string $origin, array $allowedOrigins): void { - $this->app['config']->set('reverb.apps.apps.0.allowed_origins', $allowedOrigins); + config()->set('reverb.apps.apps.0.allowed_origins', $allowedOrigins); $this->server->open($connection = new FakeConnection(origin: $origin)); $this->assertTrue($connection->isEstablished()); @@ -449,7 +450,7 @@ public static function validOriginProvider(): array public function testRejectsAConnectionWhenTheAppIsOverTheConnectionLimit(): void { - $this->app['config']->set('reverb.apps.apps.0.max_connections', 1); + config()->set('reverb.apps.apps.0.max_connections', 1); $this->server->open($connection = new FakeConnection); $this->server->message( $connection, @@ -631,7 +632,7 @@ public function testSendsAnErrorIfSomethingFailsForChannelType(): void public function testRejectsAMessageWhenTheRateLimitIsExceeded(): void { - $this->app['config']->set('reverb.apps.apps.0.rate_limiting', [ + config()->set('reverb.apps.apps.0.rate_limiting', [ 'enabled' => true, 'max_attempts' => 3, 'decay_seconds' => 1, @@ -671,7 +672,7 @@ public function testRejectsAMessageWhenTheRateLimitIsExceeded(): void public function testEnforcesRateLimitConfiguredWithNumericStrings(): void { - $this->app['config']->set('reverb.apps.apps.0.rate_limiting', [ + config()->set('reverb.apps.apps.0.rate_limiting', [ 'enabled' => true, 'max_attempts' => '1', 'decay_seconds' => '60', @@ -708,7 +709,7 @@ public function testEnforcesRateLimitConfiguredWithNumericStrings(): void #[DefineEnvironment('withInvalidRateLimiterConfiguration')] public function testMessageRateLimiterIsIndependentOfRateLimiterConfiguration(): void { - $this->app['config']->set('reverb.apps.apps.0.rate_limiting', [ + config()->set('reverb.apps.apps.0.rate_limiting', [ 'enabled' => true, 'max_attempts' => 1, 'decay_seconds' => 60, @@ -762,7 +763,7 @@ protected function withInvalidRateLimiterConfiguration(ApplicationContract $app) public function testCloseClearsInitializedMessageRateLimiterState(): void { - $this->app['config']->set('reverb.apps.apps.0.rate_limiting', [ + config()->set('reverb.apps.apps.0.rate_limiting', [ 'enabled' => true, 'max_attempts' => 1, 'decay_seconds' => 60, @@ -804,7 +805,7 @@ public function testCloseClearsInitializedMessageRateLimiterState(): void public function testTerminatesTheConnectionWhenRateLimitIsExceededAndConfiguredToTerminate(): void { - $this->app['config']->set('reverb.apps.apps.0.rate_limiting', [ + config()->set('reverb.apps.apps.0.rate_limiting', [ 'enabled' => true, 'max_attempts' => 1, 'decay_seconds' => 1, @@ -842,7 +843,7 @@ public function testTerminatesTheConnectionWhenRateLimitIsExceededAndConfiguredT public function testTerminatesTheConnectionWhenSendingTheRateLimitErrorFails(): void { - $this->app['config']->set('reverb.apps.apps.0.rate_limiting', [ + config()->set('reverb.apps.apps.0.rate_limiting', [ 'enabled' => true, 'max_attempts' => 1, 'decay_seconds' => 1, @@ -876,7 +877,7 @@ public function testTerminatesTheConnectionWhenSendingTheRateLimitErrorFails(): public function testEnabledRateLimitingRequiresDecaySeconds(): void { - $this->app['config']->set('reverb.apps.apps.0.rate_limiting', [ + config()->set('reverb.apps.apps.0.rate_limiting', [ 'enabled' => true, 'max_attempts' => 1, 'terminate_on_limit' => false, @@ -964,7 +965,7 @@ public function testCloseDoesNotTerminateTheConnection(): void $server->close($connection); // close() is the "client already disconnected" cleanup path. - // It should NOT try to terminate/disconnect the connection again — + // It should not try to terminate/disconnect the connection again — // the fd is already gone. $this->assertFalse($connection->wasTerminated); } @@ -1004,7 +1005,7 @@ public function testConnectionEstablishedEventNotDispatchedOnFailure(): void { Event::fake(); - $this->app['config']->set('reverb.apps.apps.0.allowed_origins', ['laravel.com']); + config()->set('reverb.apps.apps.0.allowed_origins', ['laravel.com']); $this->server->open(new FakeConnection(origin: 'http://localhost')); Event::assertNotDispatched(ConnectionEstablished::class); diff --git a/tests/Reverb/ReverbTestCase.php b/tests/Reverb/ReverbTestCase.php index 40137ae67..9322bc3e8 100644 --- a/tests/Reverb/ReverbTestCase.php +++ b/tests/Reverb/ReverbTestCase.php @@ -43,7 +43,9 @@ protected function getPackageProviders(ApplicationContract $app): array */ protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('reverb.apps.apps', [ + $config = $app->make('config'); + + $config->set('reverb.apps.apps', [ [ 'key' => 'reverb-key', 'secret' => 'reverb-secret', @@ -76,10 +78,10 @@ protected function defineEnvironment(ApplicationContract $app): void ], ]; - $app['config']->set('database.redis.options', []); - $app['config']->set('database.redis.default', $redisConnection); - $app['config']->set('database.redis.queue', $redisConnection); - $app['config']->set('database.redis.reverb', $redisConnection); + $config->set('database.redis.options', []); + $config->set('database.redis.default', $redisConnection); + $config->set('database.redis.queue', $redisConnection); + $config->set('database.redis.reverb', $redisConnection); $server = m::mock(Server::class); $server->shouldReceive('sendMessage')->zeroOrMoreTimes(); diff --git a/tests/Reverb/Servers/Hypervel/GracefulShutdownTest.php b/tests/Reverb/Servers/Hypervel/GracefulShutdownTest.php index 5bad10aec..c0c89635a 100644 --- a/tests/Reverb/Servers/Hypervel/GracefulShutdownTest.php +++ b/tests/Reverb/Servers/Hypervel/GracefulShutdownTest.php @@ -9,12 +9,16 @@ use Hypervel\Core\Events\OnWorkerExit; use Hypervel\Filesystem\Filesystem; use Hypervel\Reverb\Application; +use Hypervel\Reverb\Connection as ReverbConnection; +use Hypervel\Reverb\Contracts\ApplicationProvider; use Hypervel\Reverb\Protocols\Pusher\Server as PusherServer; use Hypervel\Reverb\ReverbServiceProvider; use Hypervel\Reverb\ServerProviderManager; +use Hypervel\Reverb\Servers\Hypervel\Connection as WebSocketConnection; use Hypervel\Reverb\Servers\Hypervel\ConnectionLifecycle; use Hypervel\Reverb\Servers\Hypervel\Contracts\PubSubProvider; use Hypervel\Reverb\Servers\Hypervel\Contracts\SharedState; +use Hypervel\Reverb\Servers\Hypervel\HypervelServerProvider; use Hypervel\Reverb\Servers\Hypervel\WebSocketHandler; use Hypervel\Reverb\Webhooks\DeferredWebhookManager; use Hypervel\Reverb\Webhooks\Jobs\FlushWebhookBatchJob; @@ -202,7 +206,7 @@ public function testFlushWebhookBuffersSchedulesFlushJob(): void { Queue::fake([FlushWebhookBatchJob::class]); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['channel_occupied'], 'batching' => ['enabled' => true], @@ -224,7 +228,7 @@ public function testFlushWebhookBuffersSkipsWhenNoBatching(): void { Queue::fake([FlushWebhookBatchJob::class]); - // Default config has no batching + // Default config disables batching. $provider = $this->app->getProvider(ReverbServiceProvider::class); $method = new ReflectionMethod($provider, 'flushWebhookBuffers'); $method->invoke($provider); @@ -236,7 +240,7 @@ public function testFlushWebhookBuffersSkipsWhenBufferEmpty(): void { Queue::fake([FlushWebhookBatchJob::class]); - $this->app['config']->set('reverb.apps.apps.0.webhooks', [ + config()->set('reverb.apps.apps.0.webhooks', [ 'url' => 'https://example.com/webhook', 'events' => ['channel_occupied'], 'batching' => ['enabled' => true], @@ -323,11 +327,11 @@ public function testShutdownDoesNotLosePreExistingDeferredWebhooks(): void public function testDisconnectScalingSubscriberCallsDisconnect(): void { - $this->app['config']->set('reverb.servers.reverb.scaling.enabled', true); + config()->set('reverb.servers.reverb.scaling.enabled', true); - $provider = new \Hypervel\Reverb\Servers\Hypervel\HypervelServerProvider( + $provider = new HypervelServerProvider( $this->app, - $this->app['config']->get('reverb.servers.reverb', []) + config()->array('reverb.servers.reverb') ); $provider->register(); $this->app->make(ServerProviderManager::class)->withPublishing(); @@ -359,7 +363,7 @@ public function testDisconnectWithNoCodeUsesPlainPath(): void $sender = m::mock(Sender::class); $sender->shouldReceive('disconnect')->once()->with(99)->andReturn(true); - $wsConnection = new \Hypervel\Reverb\Servers\Hypervel\Connection($sender, 99); + $wsConnection = new WebSocketConnection($sender, 99); $wsConnection->close(); } @@ -368,13 +372,13 @@ public function testDisconnectWithCodeForwardsCodeAndReason(): void $sender = m::mock(Sender::class); $sender->shouldReceive('disconnect')->once()->with(99, 1001, 'Server restarting')->andReturn(true); - $wsConnection = new \Hypervel\Reverb\Servers\Hypervel\Connection($sender, 99); + $wsConnection = new WebSocketConnection($sender, 99); $wsConnection->close(code: 1001, reason: 'Server restarting'); } // ── Helpers ─────────────────────────────────────────────────────── - protected function createReverbConnection(?Sender $sender = null, ?int $fd = null): \Hypervel\Reverb\Connection + protected function createReverbConnection(?Sender $sender = null, ?int $fd = null): ReverbConnection { if ($sender === null) { $sender = m::mock(Sender::class); @@ -382,13 +386,13 @@ protected function createReverbConnection(?Sender $sender = null, ?int $fd = nul $sender->shouldReceive('disconnect')->zeroOrMoreTimes()->andReturn(true); } - $wsConnection = new \Hypervel\Reverb\Servers\Hypervel\Connection($sender, $fd ?? rand(1, 99999)); - $app = $this->app->make(\Hypervel\Reverb\Contracts\ApplicationProvider::class)->all()->first(); + $wsConnection = new WebSocketConnection($sender, $fd ?? rand(1, 99999)); + $app = $this->app->make(ApplicationProvider::class)->all()->first(); - return new \Hypervel\Reverb\Connection($wsConnection, $app, null); + return new ReverbConnection($wsConnection, $app, null); } - protected function addToWebSocketHandler(int $fd, \Hypervel\Reverb\Connection $connection): void + protected function addToWebSocketHandler(int $fd, ReverbConnection $connection): void { $connection->markEstablished(); $lifecycle = new ConnectionLifecycle($fd); diff --git a/tests/Reverb/Servers/Hypervel/HypervelServerProviderTest.php b/tests/Reverb/Servers/Hypervel/HypervelServerProviderTest.php index 4b80e4d86..50dfef9c3 100644 --- a/tests/Reverb/Servers/Hypervel/HypervelServerProviderTest.php +++ b/tests/Reverb/Servers/Hypervel/HypervelServerProviderTest.php @@ -28,12 +28,12 @@ public function testBindsSwooleTableSharedStateByDefault(): void public function testBindsRedisSharedStateWhenScalingEnabled(): void { - $this->app['config']->set('reverb.servers.reverb.scaling.enabled', true); + config()->set('reverb.servers.reverb.scaling.enabled', true); // Re-register the provider with new config $provider = new HypervelServerProvider( $this->app, - $this->app['config']->get('reverb.servers.reverb', []) + config()->array('reverb.servers.reverb') ); $provider->register(); @@ -52,11 +52,11 @@ public function testCreatesSwooleTableWithConfiguredRows(): void public function testScalingSharedStateDefaultsToReverbRedisConnection(): void { - $this->app['config']->set('reverb.servers.reverb.scaling.enabled', true); + config()->set('reverb.servers.reverb.scaling.enabled', true); $provider = new HypervelServerProvider( $this->app, - $this->app['config']->get('reverb.servers.reverb', []) + config()->array('reverb.servers.reverb') ); $provider->register(); @@ -68,12 +68,12 @@ public function testScalingSharedStateDefaultsToReverbRedisConnection(): void public function testScalingSharedStateUsesConfiguredRedisConnection(): void { - $this->app['config']->set('reverb.servers.reverb.scaling.enabled', true); - $this->app['config']->set('reverb.servers.reverb.scaling.connection', 'queue'); + config()->set('reverb.servers.reverb.scaling.enabled', true); + config()->set('reverb.servers.reverb.scaling.connection', 'queue'); $provider = new HypervelServerProvider( $this->app, - $this->app['config']->get('reverb.servers.reverb', []) + config()->array('reverb.servers.reverb') ); $provider->register(); diff --git a/tests/Sentry/ConfigTest.php b/tests/Sentry/ConfigTest.php index 0fd8dd12b..bf96a42a2 100644 --- a/tests/Sentry/ConfigTest.php +++ b/tests/Sentry/ConfigTest.php @@ -70,12 +70,12 @@ public static function unsupportedPoolOptions(): array public function testOldPoolsKeyIsNotUsed(): void { - $this->assertNull($this->app['config']->get('pools.sentry')); + $this->assertNull($this->app->make('config')->get('pools.sentry')); } public function testRedisFeatureIsInDefaultFeaturesConfig(): void { - $features = $this->app['config']->get('sentry.features', []); + $features = $this->app->make('config')->array('sentry.features'); $this->assertContains(RedisFeature::class, $features); } diff --git a/tests/Sentry/EventHandler/DatabaseEventsTest.php b/tests/Sentry/EventHandler/DatabaseEventsTest.php index 80c100f0c..fa8d382a4 100644 --- a/tests/Sentry/EventHandler/DatabaseEventsTest.php +++ b/tests/Sentry/EventHandler/DatabaseEventsTest.php @@ -17,7 +17,7 @@ public function testSqlQueriesAreRecordedWhenEnabled(): void 'sentry.breadcrumbs.sql_queries' => true, ]); - $this->assertTrue($this->app['config']->get('sentry.breadcrumbs.sql_queries')); + $this->assertTrue($this->app->make('config')->boolean('sentry.breadcrumbs.sql_queries')); $this->dispatchHypervelEvent(new QueryExecuted( $query = 'SELECT * FROM breadcrumbs WHERE bindings = ?;', @@ -37,7 +37,7 @@ public function testSqlBindingsAreRecordedWhenEnabled(): void 'sentry.breadcrumbs.sql_bindings' => true, ]); - $this->assertTrue($this->app['config']->get('sentry.breadcrumbs.sql_bindings')); + $this->assertTrue($this->app->make('config')->boolean('sentry.breadcrumbs.sql_bindings')); $this->dispatchHypervelEvent(new QueryExecuted( $query = 'SELECT * FROM breadcrumbs WHERE bindings = ?;', @@ -58,7 +58,7 @@ public function testSqlQueriesAreRecordedWhenDisabled(): void 'sentry.breadcrumbs.sql_queries' => false, ]); - $this->assertFalse($this->app['config']->get('sentry.breadcrumbs.sql_queries')); + $this->assertFalse($this->app->make('config')->boolean('sentry.breadcrumbs.sql_queries')); $this->dispatchHypervelEvent(new QueryExecuted( 'SELECT * FROM breadcrumbs WHERE bindings = ?;', @@ -76,7 +76,7 @@ public function testSqlBindingsAreRecordedWhenDisabled(): void 'sentry.breadcrumbs.sql_bindings' => false, ]); - $this->assertFalse($this->app['config']->get('sentry.breadcrumbs.sql_bindings')); + $this->assertFalse($this->app->make('config')->boolean('sentry.breadcrumbs.sql_bindings')); $this->dispatchHypervelEvent(new QueryExecuted( $query = 'SELECT * FROM breadcrumbs WHERE bindings <> ?;', diff --git a/tests/Sentry/EventHandler/LogEventsTest.php b/tests/Sentry/EventHandler/LogEventsTest.php index cf24814fe..e3bd43b94 100644 --- a/tests/Sentry/EventHandler/LogEventsTest.php +++ b/tests/Sentry/EventHandler/LogEventsTest.php @@ -15,7 +15,7 @@ public function testHypervelLogsAreRecordedWhenEnabled(): void 'sentry.breadcrumbs.logs' => true, ]); - $this->assertTrue($this->app['config']->get('sentry.breadcrumbs.logs')); + $this->assertTrue($this->app->make('config')->boolean('sentry.breadcrumbs.logs')); $this->dispatchHypervelEvent(new MessageLogged( $level = 'debug', @@ -36,7 +36,7 @@ public function testHypervelLogsAreRecordedWhenDisabled(): void 'sentry.breadcrumbs.logs' => false, ]); - $this->assertFalse($this->app['config']->get('sentry.breadcrumbs.logs')); + $this->assertFalse($this->app->make('config')->boolean('sentry.breadcrumbs.logs')); $this->dispatchHypervelEvent(new MessageLogged('debug', 'test message')); diff --git a/tests/Sentry/Features/CacheIntegrationTest.php b/tests/Sentry/Features/CacheIntegrationTest.php index a8893548e..fd6c20378 100644 --- a/tests/Sentry/Features/CacheIntegrationTest.php +++ b/tests/Sentry/Features/CacheIntegrationTest.php @@ -66,7 +66,7 @@ public function testCacheBreadcrumbIsNotRecordedWhenDisabled(): void 'sentry.breadcrumbs.cache' => false, ]); - $this->assertFalse($this->app['config']->get('sentry.breadcrumbs.cache')); + $this->assertFalse($this->app->make('config')->boolean('sentry.breadcrumbs.cache')); Cache::get('foo'); @@ -76,7 +76,7 @@ public function testCacheBreadcrumbIsNotRecordedWhenDisabled(): void public function testCacheBreadcrumbReplacesSessionKeyWithPlaceholder(): void { $this->startSession(); - $sessionId = $this->app['session']->getId(); + $sessionId = $this->app->make('session')->getId(); Cache::put($sessionId, 'session-data'); @@ -255,7 +255,7 @@ public function testCacheSpanReplacesSessionKeyWithPlaceholder(): void $this->markSkippedIfTracingEventsNotAvailable(); $this->startSession(); - $sessionId = $this->app['session']->getId(); + $sessionId = $this->app->make('session')->getId(); $span = $this->executeAndReturnMostRecentSpan(function () use ($sessionId) { Cache::get($sessionId); @@ -271,7 +271,7 @@ public function testCacheSpanReplacesMultipleSessionKeysWithPlaceholder(): void $this->markSkippedIfTracingEventsNotAvailable(); $this->startSession(); - $sessionId = $this->app['session']->getId(); + $sessionId = $this->app->make('session')->getId(); $span = $this->executeAndReturnMostRecentSpan(function () use ($sessionId) { Cache::get([$sessionId, 'regular-key', $sessionId . '_another']); @@ -293,7 +293,7 @@ public function testCacheOperationDoesNotStartSessionPrematurely(): void }); // Check that session was not started - $this->assertFalse($this->app['session']->isStarted()); + $this->assertFalse($this->app->make('session')->isStarted()); // And the key should not be replaced $this->assertEquals('some-key', $span->getDescription()); diff --git a/tests/Sentry/Features/ConsoleIntegrationTest.php b/tests/Sentry/Features/ConsoleIntegrationTest.php index 984782d83..e2ab2ff90 100644 --- a/tests/Sentry/Features/ConsoleIntegrationTest.php +++ b/tests/Sentry/Features/ConsoleIntegrationTest.php @@ -17,7 +17,7 @@ public function testCommandBreadcrumbIsRecordedWhenEnabled(): void 'sentry.breadcrumbs.command_info' => true, ]); - $this->assertTrue($this->app['config']->get('sentry.breadcrumbs.command_info')); + $this->assertTrue($this->app->make('config')->boolean('sentry.breadcrumbs.command_info')); $this->dispatchCommandStartEvent(); @@ -33,7 +33,7 @@ public function testCommandBreadcrumbIsNotRecordedWhenDisabled(): void 'sentry.breadcrumbs.command_info' => false, ]); - $this->assertFalse($this->app['config']->get('sentry.breadcrumbs.command_info')); + $this->assertFalse($this->app->make('config')->boolean('sentry.breadcrumbs.command_info')); $this->dispatchCommandStartEvent(); diff --git a/tests/Sentry/Features/LogIntegrationTest.php b/tests/Sentry/Features/LogIntegrationTest.php index 2a5c6b2e0..06ab80b6e 100644 --- a/tests/Sentry/Features/LogIntegrationTest.php +++ b/tests/Sentry/Features/LogIntegrationTest.php @@ -23,7 +23,7 @@ protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - tap($app['config'], static function (Repository $config) { + tap($app->make('config'), static function (Repository $config) { $config->set('logging.channels.sentry', [ 'driver' => 'sentry', ]); diff --git a/tests/Sentry/Features/LogLogsIntegrationTest.php b/tests/Sentry/Features/LogLogsIntegrationTest.php index b8baf3d47..a17ba1b1b 100644 --- a/tests/Sentry/Features/LogLogsIntegrationTest.php +++ b/tests/Sentry/Features/LogLogsIntegrationTest.php @@ -27,7 +27,7 @@ protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - tap($app['config'], static function (Repository $config) { + tap($app->make('config'), static function (Repository $config) { $config->set('sentry.enable_logs', true); $config->set('logging.channels.sentry_logs', [ diff --git a/tests/Sentry/Features/QueueIntegrationTest.php b/tests/Sentry/Features/QueueIntegrationTest.php index 0b50bafc6..4da98f398 100644 --- a/tests/Sentry/Features/QueueIntegrationTest.php +++ b/tests/Sentry/Features/QueueIntegrationTest.php @@ -39,21 +39,25 @@ class QueueIntegrationTest extends SentryTestCase protected function withTracingEnabled(ApplicationContract $app): void { - $app['config']->set('sentry.traces_sample_rate', 1.0); + $app->make('config')->set('sentry.traces_sample_rate', 1.0); } protected function withQueueJobTracingDisabled(ApplicationContract $app): void { - $app['config']->set('sentry.traces_sample_rate', 1.0); - $app['config']->set('sentry.tracing.queue_job_transactions', false); + $config = $app->make('config'); + + $config->set('sentry.traces_sample_rate', 1.0); + $config->set('sentry.tracing.queue_job_transactions', false); } protected function withLocalQueueOutputDisabled(ApplicationContract $app): void { - $app['config']->set('sentry.traces_sample_rate', null); - $app['config']->set('sentry.breadcrumbs.queue_info', false); - $app['config']->set('sentry.tracing.queue_jobs', false); - $app['config']->set('sentry.tracing.queue_job_transactions', false); + $config = $app->make('config'); + + $config->set('sentry.traces_sample_rate', null); + $config->set('sentry.breadcrumbs.queue_info', false); + $config->set('sentry.tracing.queue_jobs', false); + $config->set('sentry.tracing.queue_job_transactions', false); } public function testQueueJobPushesAndPopsScopeWithBreadcrumbs(): void diff --git a/tests/Sentry/Features/RedisIntegrationTest.php b/tests/Sentry/Features/RedisIntegrationTest.php index 455cb07c2..5c2cad14a 100644 --- a/tests/Sentry/Features/RedisIntegrationTest.php +++ b/tests/Sentry/Features/RedisIntegrationTest.php @@ -108,7 +108,7 @@ public function testRedisCommandWithSessionKeyReplacesWithPlaceholder(): void { $this->setupMocks(); $this->startSession(); - $sessionId = $this->app['session']->getId(); + $sessionId = $this->app->make('session')->getId(); $transaction = $this->startTransaction(); $dispatcher = $this->app->make(Dispatcher::class); @@ -130,7 +130,7 @@ public function testRedisParametersRequirePiiConsentAndRedactSessionKey(): void $this->app->make(RedisFeature::class)->detectSessionKeyOnConsole = true; $this->setupMocks(); $this->startSession(); - $sessionId = $this->app['session']->getId(); + $sessionId = $this->app->make('session')->getId(); $transaction = $this->startTransaction(); $dispatcher = $this->app->make(Dispatcher::class); diff --git a/tests/Sentry/Features/StrictTraceContinuationIntegrationTest.php b/tests/Sentry/Features/StrictTraceContinuationIntegrationTest.php index e60f37944..7a3d57b8b 100644 --- a/tests/Sentry/Features/StrictTraceContinuationIntegrationTest.php +++ b/tests/Sentry/Features/StrictTraceContinuationIntegrationTest.php @@ -19,7 +19,7 @@ class StrictTraceContinuationIntegrationTest extends SentryTestCase private function registerRoutes(): void { - $this->app['router']->group(['prefix' => 'sentry'], function (Router $router) { + $this->app->make('router')->group(['prefix' => 'sentry'], function (Router $router) { $router->get('/strict-trace-continuation', function () { return 'ok'; }); diff --git a/tests/Sentry/SentryTestCase.php b/tests/Sentry/SentryTestCase.php index 1a289f7ba..59da2b4d4 100644 --- a/tests/Sentry/SentryTestCase.php +++ b/tests/Sentry/SentryTestCase.php @@ -36,7 +36,7 @@ protected function defineEnvironment(ApplicationContract $app): void self::$lastSentryEvents = []; $this->setupGlobalEventProcessor(); - tap($app['config'], function (Repository $config) { + tap($app->make('config'), function (Repository $config) { $config->set('sentry.before_send', static function (Event $event, ?EventHint $hint) { self::$lastSentryEvents[] = [$event, $hint]; @@ -57,13 +57,15 @@ protected function defineEnvironment(ApplicationContract $app): void protected function envWithoutDsnSet(ApplicationContract $app): void { - $app['config']->set('sentry.dsn', null); - $app['config']->set('sentry_test.override_dsn', true); + $config = $app->make('config'); + + $config->set('sentry.dsn', null); + $config->set('sentry_test.override_dsn', true); } protected function envSamplingAllTransactions(ApplicationContract $app): void { - $app['config']->set('sentry.traces_sample_rate', 1.0); + $app->make('config')->set('sentry.traces_sample_rate', 1.0); } protected function getPackageProviders(ApplicationContract $app): array diff --git a/tests/Sentry/ServiceProviderWithCustomAliasTest.php b/tests/Sentry/ServiceProviderWithCustomAliasTest.php index c099d87e0..abd4f40db 100644 --- a/tests/Sentry/ServiceProviderWithCustomAliasTest.php +++ b/tests/Sentry/ServiceProviderWithCustomAliasTest.php @@ -14,8 +14,10 @@ class ServiceProviderWithCustomAliasTest extends TestCase { protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('custom-sentry.dsn', 'http://publickey@sentry.dev/123'); - $app['config']->set('custom-sentry.error_types', E_ALL ^ E_DEPRECATED ^ E_USER_DEPRECATED); + $config = $app->make('config'); + + $config->set('custom-sentry.dsn', 'http://publickey@sentry.dev/123'); + $config->set('custom-sentry.error_types', E_ALL ^ E_DEPRECATED ^ E_USER_DEPRECATED); } protected function getPackageProviders(ApplicationContract $app): array diff --git a/tests/Sentry/ServiceProviderWithoutDsnTest.php b/tests/Sentry/ServiceProviderWithoutDsnTest.php index fdc33c917..ddb29c902 100644 --- a/tests/Sentry/ServiceProviderWithoutDsnTest.php +++ b/tests/Sentry/ServiceProviderWithoutDsnTest.php @@ -18,7 +18,7 @@ class ServiceProviderWithoutDsnTest extends TestCase { protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('sentry.dsn', null); + $app->make('config')->set('sentry.dsn', null); } protected function getPackageProviders(ApplicationContract $app): array diff --git a/tests/Support/SupportCapsuleManagerTraitTest.php b/tests/Support/SupportCapsuleManagerTraitTest.php index 2a05bba0f..f21e135a9 100644 --- a/tests/Support/SupportCapsuleManagerTraitTest.php +++ b/tests/Support/SupportCapsuleManagerTraitTest.php @@ -15,23 +15,23 @@ class SupportCapsuleManagerTraitTest extends TestCase { use CapsuleManagerTrait; - public function testSetupContainerForCapsule() + public function testSetupContainerForCapsule(): void { $app = new Container; $this->setupContainer($app); - $this->assertEquals($app, $this->getContainer()); - $this->assertInstanceOf(Fluent::class, $app['config']); + $this->assertSame($app, $this->getContainer()); + $this->assertInstanceOf(Fluent::class, $app->make('config')); } - public function testSetupContainerForCapsuleWhenConfigIsBound() + public function testSetupContainerForCapsuleWhenConfigIsBound(): void { $app = new Container; - $app['config'] = new Repository([]); + $app->instance('config', new Repository([])); $this->setupContainer($app); - $this->assertEquals($app, $this->getContainer()); - $this->assertInstanceOf(Repository::class, $app['config']); + $this->assertSame($app, $this->getContainer()); + $this->assertInstanceOf(Repository::class, $app->make('config')); } public function testFlushStateClearsGlobalInstance() diff --git a/tests/Support/SupportFacadeTest.php b/tests/Support/SupportFacadeTest.php index 5e8f4389c..22408d6d0 100755 --- a/tests/Support/SupportFacadeTest.php +++ b/tests/Support/SupportFacadeTest.php @@ -4,7 +4,7 @@ namespace Hypervel\Tests\Support\SupportFacadeTest; -use ArrayAccess; +use Hypervel\Container\Container; use Hypervel\Support\Facades\Facade; use Hypervel\Support\Testing\Fakes\Fake; use Hypervel\Tests\TestCase; @@ -22,29 +22,29 @@ protected function setUp(): void FacadeStub::setFacadeApplication(null); } - public function testFacadeCallsUnderlyingApplication() + public function testFacadeCallsUnderlyingApplication(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => $mock = m::mock(stdClass::class)]); + $app->setInstances(['foo' => $mock = m::mock(stdClass::class)]); $mock->shouldReceive('bar')->once()->andReturn('baz'); FacadeStub::setFacadeApplication($app); $this->assertSame('baz', FacadeStub::bar()); } - public function testShouldReceiveReturnsAMockeryMock() + public function testShouldReceiveReturnsAMockeryMock(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => new stdClass]); + $app->setInstances(['foo' => new stdClass]); FacadeStub::setFacadeApplication($app); $this->assertInstanceOf(MockInterface::class, $mock = FacadeStub::shouldReceive('foo')->once()->with('bar')->andReturn('baz')->getMock()); - $this->assertSame('baz', $app['foo']->foo('bar')); + $this->assertSame('baz', $app->make('foo')->foo('bar')); } - public function testSpyReturnsAMockerySpy() + public function testSpyReturnsAMockerySpy(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => new stdClass]); + $app->setInstances(['foo' => new stdClass]); FacadeStub::setFacadeApplication($app); $this->assertInstanceOf(MockInterface::class, $spy = FacadeStub::spy()); @@ -53,16 +53,16 @@ public function testSpyReturnsAMockerySpy() $spy->shouldHaveReceived('foo'); } - public function testShouldReceiveCanBeCalledTwice() + public function testShouldReceiveCanBeCalledTwice(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => new stdClass]); + $app->setInstances(['foo' => new stdClass]); FacadeStub::setFacadeApplication($app); $this->assertInstanceOf(MockInterface::class, FacadeStub::shouldReceive('foo')->once()->with('bar')->andReturn('baz')->getMock()); $this->assertInstanceOf(MockInterface::class, FacadeStub::shouldReceive('foo2')->once()->with('bar2')->andReturn('baz2')->getMock()); - $this->assertSame('baz', $app['foo']->foo('bar')); - $this->assertSame('baz2', $app['foo']->foo2('bar2')); + $this->assertSame('baz', $app->make('foo')->foo('bar')); + $this->assertSame('baz2', $app->make('foo')->foo2('bar2')); } public function testCanBeMockedWithoutUnderlyingInstance() @@ -71,20 +71,20 @@ public function testCanBeMockedWithoutUnderlyingInstance() $this->assertSame('bar', FacadeStub::foo()); } - public function testExpectsReturnsAMockeryMockWithExpectationRequired() + public function testExpectsReturnsAMockeryMockWithExpectationRequired(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => new stdClass]); + $app->setInstances(['foo' => new stdClass]); FacadeStub::setFacadeApplication($app); $this->assertInstanceOf(MockInterface::class, $mock = FacadeStub::expects('foo')->with('bar')->andReturn('baz')->getMock()); - $this->assertSame('baz', $app['foo']->foo('bar')); + $this->assertSame('baz', $app->make('foo')->foo('bar')); } - public function testFacadeResolvesAgainAfterClearingSpecific() + public function testFacadeResolvesAgainAfterClearingSpecific(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => $mock = m::mock(stdClass::class)]); + $app->setInstances(['foo' => $mock = m::mock(stdClass::class)]); $mock->shouldReceive('bar')->times(3)->andReturn('baz'); // Resolve for the first time @@ -100,10 +100,10 @@ public function testFacadeResolvesAgainAfterClearingSpecific() $this->assertSame('baz', FacadeStub::bar()); } - public function testFacadeResolvesAgainAfterClearingAll() + public function testFacadeResolvesAgainAfterClearingAll(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => $mock = m::mock(stdClass::class)]); + $app->setInstances(['foo' => $mock = m::mock(stdClass::class)]); $mock->shouldReceive('bar')->times(2)->andReturn('baz'); // Resolve for the first time @@ -135,16 +135,16 @@ public function testSetFacadeApplicationToNullClearsApp() $this->assertNull(FacadeStub::getFacadeApplication()); } - public function testSwapSetsInstanceOnApp() + public function testSwapSetsInstanceOnApp(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => new stdClass]); + $app->setInstances(['foo' => new stdClass]); FacadeStub::setFacadeApplication($app); $replacement = new stdClass; FacadeStub::swap($replacement); - $this->assertSame($replacement, $app['foo']); + $this->assertSame($replacement, $app->make('foo')); $this->assertSame($replacement, FacadeStub::getFacadeRoot()); } @@ -176,26 +176,26 @@ public function testIsFakeReturnsTrueForFakeInstance() $this->assertTrue(FacadeStub::isFake()); } - public function testIsFakeReturnsFalseForNonFakeInstance() + public function testIsFakeReturnsFalseForNonFakeInstance(): void { $app = new ApplicationStub; - $app->setAttributes(['foo' => new stdClass]); + $app->setInstances(['foo' => new stdClass]); FacadeStub::setFacadeApplication($app); $this->assertFalse(FacadeStub::isFake()); } - public function testUncachedFacadeResolvesEachTime() + public function testUncachedFacadeResolvesEachTime(): void { $app = new CountingApplicationStub; - $app->setAttributes(['uncached' => new stdClass]); + $app->setInstances(['uncached' => new stdClass]); UncachedFacadeStub::setFacadeApplication($app); UncachedFacadeStub::getFacadeRoot(); UncachedFacadeStub::getFacadeRoot(); - // offsetGet should be called twice since $cached = false - $this->assertSame(2, $app->offsetGetCount); + // The container should be queried twice since $cached = false. + $this->assertSame(2, $app->makeCount); } } @@ -207,38 +207,13 @@ protected static function getFacadeAccessor(): string } } -class ApplicationStub implements ArrayAccess +class ApplicationStub extends Container { - protected array $attributes = []; - - public function setAttributes(array $attributes): void - { - $this->attributes = $attributes; - } - - public function instance(string $key, mixed $instance): void - { - $this->attributes[$key] = $instance; - } - - public function offsetExists($offset): bool - { - return isset($this->attributes[$offset]); - } - - public function offsetGet($key): mixed - { - return $this->attributes[$key]; - } - - public function offsetSet($key, $value): void - { - $this->attributes[$key] = $value; - } - - public function offsetUnset($key): void + public function setInstances(array $instances): void { - unset($this->attributes[$key]); + foreach ($instances as $key => $instance) { + $this->instance($key, $instance); + } } } @@ -258,12 +233,12 @@ protected static function getFacadeAccessor(): string class CountingApplicationStub extends ApplicationStub { - public int $offsetGetCount = 0; + public int $makeCount = 0; - public function offsetGet($key): mixed + public function make(string $abstract, array $parameters = []): mixed { - ++$this->offsetGetCount; + ++$this->makeCount; - return parent::offsetGet($key); + return parent::make($abstract, $parameters); } } diff --git a/tests/Support/SupportMaintenanceModeTest.php b/tests/Support/SupportMaintenanceModeTest.php index fb4813f12..a19f4c3cf 100644 --- a/tests/Support/SupportMaintenanceModeTest.php +++ b/tests/Support/SupportMaintenanceModeTest.php @@ -11,11 +11,11 @@ class SupportMaintenanceModeTest extends TestCase { - public function testExtend() + public function testExtend(): void { MaintenanceMode::extend('test', fn () => new TestMaintenanceMode); - $this->app->config->set('app.maintenance.driver', 'test'); + $this->app->make('config')->set('app.maintenance.driver', 'test'); $driver = $this->app->make(MaintenanceModeManager::class)->driver(); @@ -24,7 +24,9 @@ public function testExtend() public function testCacheDriverPreservesZeroStoreAndEmptyFallback(): void { - $this->app->config->set([ + $config = $this->app->make('config'); + + $config->set([ 'app.maintenance.driver' => 'cache', 'cache.default' => 'array', 'cache.stores.0' => ['driver' => 'array'], @@ -32,7 +34,7 @@ public function testCacheDriverPreservesZeroStoreAndEmptyFallback(): void ]); $this->app->make('cache')->store('0')->put('hypervel:foundation:down', ['store' => 'zero']); - $this->app->config->set('app.maintenance.store', '0'); + $config->set('app.maintenance.store', '0'); $this->assertSame( ['store' => 'zero'], @@ -40,7 +42,7 @@ public function testCacheDriverPreservesZeroStoreAndEmptyFallback(): void ); $this->app->make('cache')->store('array')->put('hypervel:foundation:down', ['store' => 'default']); - $this->app->config->set('app.maintenance.store', ''); + $config->set('app.maintenance.store', ''); $this->assertSame( ['store' => 'default'], diff --git a/tests/Telescope/FeatureTestCase.php b/tests/Telescope/FeatureTestCase.php index f4ab9a4c7..16d9b7610 100644 --- a/tests/Telescope/FeatureTestCase.php +++ b/tests/Telescope/FeatureTestCase.php @@ -64,7 +64,7 @@ protected function setUp(): void $this->app->make(CacheFactoryContract::class) ->forever('telescope:dump-watcher', true); - $this->app['env'] = 'production'; + $this->app->instance('env', 'production'); // Clear any entries recorded during bootstrap (e.g. migrations). Telescope::flushEntries(); diff --git a/tests/Telescope/Watchers/ReverbWatcherTest.php b/tests/Telescope/Watchers/ReverbWatcherTest.php index bfcdae4f1..62f700ac4 100644 --- a/tests/Telescope/Watchers/ReverbWatcherTest.php +++ b/tests/Telescope/Watchers/ReverbWatcherTest.php @@ -52,7 +52,9 @@ protected function defineEnvironment(ApplicationContract $app): void { parent::defineEnvironment($app); - $app['config']->set('reverb.apps.apps', [ + $config = $app->make('config'); + + $config->set('reverb.apps.apps', [ [ 'key' => 'reverb-key', 'secret' => 'reverb-secret', @@ -85,10 +87,10 @@ protected function defineEnvironment(ApplicationContract $app): void ], ]; - $app['config']->set('database.redis.options', []); - $app['config']->set('database.redis.default', $redisConnection); - $app['config']->set('database.redis.queue', $redisConnection); - $app['config']->set('database.redis.reverb', $redisConnection); + $config->set('database.redis.options', []); + $config->set('database.redis.default', $redisConnection); + $config->set('database.redis.queue', $redisConnection); + $config->set('database.redis.reverb', $redisConnection); $server = m::mock(Server::class); $server->shouldReceive('sendMessage')->zeroOrMoreTimes(); diff --git a/tests/Testbench/AttributeEnvironmentSetupTest.php b/tests/Testbench/AttributeEnvironmentSetupTest.php index ca99499c7..f9e9cd48b 100644 --- a/tests/Testbench/AttributeEnvironmentSetupTest.php +++ b/tests/Testbench/AttributeEnvironmentSetupTest.php @@ -74,7 +74,7 @@ public function itDoesntLoadInvalidEnvironmentConfig(): void */ protected function classConfig(ApplicationContract $app): void { - $app['config']->set('testbench.class', 'testbench'); + $app->make('config')->set('testbench.class', 'testbench'); } /** @@ -82,7 +82,7 @@ protected function classConfig(ApplicationContract $app): void */ protected function globalConfig(ApplicationContract $app): void { - $app['config']->set('testbench.global', 'testbench'); + $app->make('config')->set('testbench.global', 'testbench'); } /** @@ -90,7 +90,7 @@ protected function globalConfig(ApplicationContract $app): void */ protected function firstConfig(ApplicationContract $app): void { - $app['config']->set('testbench.one', 'testbench'); + $app->make('config')->set('testbench.one', 'testbench'); } /** @@ -98,7 +98,7 @@ protected function firstConfig(ApplicationContract $app): void */ protected function secondConfig(ApplicationContract $app): void { - $app['config']->set('testbench.two', 'testbench'); + $app->make('config')->set('testbench.two', 'testbench'); } /** @@ -106,8 +106,10 @@ protected function secondConfig(ApplicationContract $app): void */ protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('database.default', 'testbench'); - $app['config']->set('database.connections.testbench', [ + $config = $app->make('config'); + + $config->set('database.default', 'testbench'); + $config->set('database.connections.testbench', [ 'driver' => 'sqlite', 'database' => ':memory:', ]); diff --git a/tests/Testbench/Attributes/ResolvesHypervelTest.php b/tests/Testbench/Attributes/ResolvesHypervelTest.php index 976cc6952..2a01f875e 100644 --- a/tests/Testbench/Attributes/ResolvesHypervelTest.php +++ b/tests/Testbench/Attributes/ResolvesHypervelTest.php @@ -16,7 +16,7 @@ class ResolvesHypervelTest extends TestCase #[ResolvesHypervel('hypervelDefaultConfiguration')] public function itCanResolveDefinedConfiguration(): void { - $this->assertSame(LoadConfiguration::class, $this->app[LoadConfiguration::class]::class); + $this->assertSame(LoadConfiguration::class, $this->app->make(LoadConfiguration::class)::class); } /** diff --git a/tests/Testbench/Attributes/UsesFrameworkConfigurationTest.php b/tests/Testbench/Attributes/UsesFrameworkConfigurationTest.php index 28792ef8e..9a573bdb7 100644 --- a/tests/Testbench/Attributes/UsesFrameworkConfigurationTest.php +++ b/tests/Testbench/Attributes/UsesFrameworkConfigurationTest.php @@ -4,8 +4,11 @@ namespace Hypervel\Tests\Testbench\Attributes; +use App\Models\User as ApplicationUser; +use Hypervel\Foundation\Auth\User as FoundationUser; use Hypervel\Foundation\Bootstrap\LoadConfiguration; use Hypervel\Testbench\Attributes\UsesFrameworkConfiguration; +use Hypervel\Testbench\Bootstrap\LoadConfiguration as TestbenchLoadConfiguration; use Hypervel\Testbench\Foundation\Env; use Hypervel\Testbench\TestCase; use PHPUnit\Framework\Attributes\Test; @@ -17,23 +20,23 @@ class UsesFrameworkConfigurationTest extends TestCase #[Test] public function itCanLoadUsingTestbenchConfigurations(): void { - $this->assertSame(\Hypervel\Testbench\Bootstrap\LoadConfiguration::class, $this->app[LoadConfiguration::class]::class); + $this->assertSame(TestbenchLoadConfiguration::class, $this->app->make(LoadConfiguration::class)::class); $environment = Env::has('TESTBENCH_PACKAGE_TESTER') ? 'testing' : 'workbench'; $this->assertSame($environment, config('app.env')); - $this->assertSame(\Hypervel\Foundation\Auth\User::class, config('auth.providers.users.model')); + $this->assertSame(FoundationUser::class, config('auth.providers.users.model')); } #[Test] #[UsesFrameworkConfiguration] public function itCanLoadUsingFrameworkConfigurations(): void { - $this->assertSame(LoadConfiguration::class, $this->app[LoadConfiguration::class]::class); + $this->assertSame(LoadConfiguration::class, $this->app->make(LoadConfiguration::class)::class); $environment = Env::has('TESTBENCH_PACKAGE_TESTER') ? 'testing' : 'production'; $this->assertSame($environment, config('app.env')); - $this->assertSame(\App\Models\User::class, config('auth.providers.users.model')); + $this->assertSame(ApplicationUser::class, config('auth.providers.users.model')); } } diff --git a/tests/Testbench/Concerns/CreatesApplicationTest.php b/tests/Testbench/Concerns/CreatesApplicationTest.php index 43ad6821e..eb1be922b 100644 --- a/tests/Testbench/Concerns/CreatesApplicationTest.php +++ b/tests/Testbench/Concerns/CreatesApplicationTest.php @@ -4,6 +4,7 @@ namespace Hypervel\Tests\Testbench\Concerns; +use Hypervel\Contracts\Events\Dispatcher; use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Foundation\Bootstrap\LoadEnvironmentVariables; use Hypervel\Testbench\TestCase; @@ -43,8 +44,7 @@ public function testGetPackageAliasesReturnsAliases(): void public function testRegisterPackageProvidersRegistersProviders(): void { - // The provider should be registered via defineEnvironment - // which calls registerPackageProviders + // The package provider is registered during application configuration. $this->assertTrue( $this->app->providerIsLoaded(TestServiceProvider::class), 'TestServiceProvider should be registered' @@ -59,21 +59,20 @@ public function testRegisterPackageAliasesAddsToConfig(): void $this->assertSame(TestFacade::class, $aliases['TestAlias']); } - public function testAfterLoadingEnvironmentFiresThroughTestbenchPath(): void + public function testAfterLoadingEnvironmentRegistersThroughTestbenchPath(): void { // The bootstrapped event should have been dispatched by bootstrapWith() // in CreatesApplication::resolveApplicationConfiguration(). - $listeners = $this->app['events']->getListeners( + $events = $this->app->make(Dispatcher::class); + $listeners = $events->getListeners( 'bootstrapped: ' . LoadEnvironmentVariables::class ); // Register a callback now and verify it gets added to the listener list. - $called = false; - $this->app->afterLoadingEnvironment(function () use (&$called) { - $called = true; + $this->app->afterLoadingEnvironment(static function (): void { }); - $updatedListeners = $this->app['events']->getListeners( + $updatedListeners = $events->getListeners( 'bootstrapped: ' . LoadEnvironmentVariables::class ); diff --git a/tests/Testbench/Concerns/DefineCacheRoutesTest.php b/tests/Testbench/Concerns/DefineCacheRoutesTest.php index e9dfe4625..3ff9458d8 100644 --- a/tests/Testbench/Concerns/DefineCacheRoutesTest.php +++ b/tests/Testbench/Concerns/DefineCacheRoutesTest.php @@ -40,7 +40,7 @@ public function testCompiledRouteCollectionIsInstalledAfterDefineCacheRoutes(): ); $this->assertInstanceOf( RouteCollection::class, - $this->app['router']->getRoutes() + $this->app->make(Router::class)->getRoutes() ); $this->defineCacheRoutes(<<<'PHP' @@ -51,7 +51,7 @@ public function testCompiledRouteCollectionIsInstalledAfterDefineCacheRoutes(): $this->assertInstanceOf( CompiledRouteCollection::class, - $this->app['router']->getRoutes() + $this->app->make(Router::class)->getRoutes() ); } @@ -91,8 +91,7 @@ public function testNamedRoutesSurviveCaching(): void Route::get('/named', fn () => 'named_response')->name('test.named'); PHP); - /** @var Router $router */ - $router = $this->app['router']; + $router = $this->app->make(Router::class); $routes = $router->getRoutes(); $this->assertNotNull($routes->getByName('test.named')); @@ -307,7 +306,7 @@ public function testSetUpApplicationRoutesSkipsWhenRoutesCached(): void // routesAreCached() should return true $this->assertTrue($this->app->routesAreCached()); - // Routes from defineRoutes() should NOT be registered since + // Routes from defineRoutes() should not be registered since // setUpApplicationRoutes returns early when routes are cached. // Only the cached /cached-only route should exist. $this->get('/cached-only')->assertOk(); diff --git a/tests/Testbench/DefaultConfigurationTest.php b/tests/Testbench/DefaultConfigurationTest.php index c7b73aea2..6e58ed62e 100644 --- a/tests/Testbench/DefaultConfigurationTest.php +++ b/tests/Testbench/DefaultConfigurationTest.php @@ -21,19 +21,19 @@ class DefaultConfigurationTest extends TestCase #[Test] public function itCanLoadUsingTestbenchConfigurations(): void { - $this->assertSame(\Hypervel\Testbench\Bootstrap\LoadConfiguration::class, \get_class($this->app[LoadConfiguration::class])); + $this->assertSame(TestbenchLoadConfiguration::class, $this->app->make(LoadConfiguration::class)::class); } #[Test] public function itPopulatesExpectedDebugConfig(): void { - $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER'), $this->app['config']['app.debug']); + $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER'), $this->app->make('config')->boolean('app.debug')); } #[Test] public function itPopulatesExpectedAppKeyConfig(): void { - $this->assertSame('AckfSECXIvnK5r28GVIWUAxmbBSjTsmF', $this->app['config']['app.key']); + $this->assertSame('AckfSECXIvnK5r28GVIWUAxmbBSjTsmF', $this->app->make('config')->string('app.key')); } #[Test] @@ -43,7 +43,7 @@ public function itPopulatesExpectedTestingConfig(): void 'driver' => 'sqlite', 'database' => ':memory:', 'foreign_key_constraints' => false, - ], $this->app['config']['database.connections.testing']); + ], $this->app->make('config')->array('database.connections.testing')); $this->assertTrue($this->usesSqliteInMemoryDatabaseConnection('testing')); $this->assertFalse($this->usesSqliteInMemoryDatabaseConnection('sqlite')); @@ -69,9 +69,10 @@ public function itUsesTheCanonicalSqliteMemoryClassification(): void #[Test] public function itFallsBackToTheTestingConnectionWhenRuntimeSqliteIsMissing(): void { - $sqliteDatabase = $this->app['config']['database.connections.sqlite.database']; + $config = $this->app->make('config'); + $sqliteDatabase = $config->string('database.connections.sqlite.database'); - $this->assertSame('testing', $this->app['config']['database.default']); + $this->assertSame('testing', $config->string('database.default')); $this->assertSame(BASE_PATH . '/database/database.sqlite', $sqliteDatabase); $this->assertFileDoesNotExist($sqliteDatabase); } @@ -116,30 +117,34 @@ public static function sqliteNonFileIdentifiers(): array #[Test] public function itPopulatesExpectedCacheDefaults(): void { - $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER') ? 'database' : 'array', $this->app['config']['cache.default']); - $this->assertFalse($this->app['config']['cache.serializable_classes']); + $config = $this->app->make('config'); + + $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER') ? 'database' : 'array', $config->string('cache.default')); + $this->assertFalse($config->boolean('cache.serializable_classes')); } #[Test] public function itPopulatesExpectedRateLimiterDefaults(): void { - $this->assertSame('worker-array', $this->app['config']['rate-limiter.default']); + $config = $this->app->make('config'); + + $this->assertSame('worker-array', $config->string('rate-limiter.default')); $this->assertSame( ['database', 'redis', 'swoole', 'worker-array'], - array_keys($this->app['config']['rate-limiter.stores']), + array_keys($config->array('rate-limiter.stores')), ); } #[Test] public function itPopulatesExpectedSessionDefaults(): void { - $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER') ? 'cookie' : 'array', $this->app['config']['session.driver']); + $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER') ? 'cookie' : 'array', $this->app->make('config')->string('session.driver')); } #[Test] public function itPopulatesExpectedRedisConnections(): void { - $connections = $this->app['config']['database.redis']; + $connections = $this->app->make('config')->array('database.redis'); $this->assertArrayHasKey('default', $connections); $this->assertArrayHasKey('cache', $connections); @@ -159,6 +164,6 @@ public function itUsesImmutableDatesByDefault(): void #[Test] public function itResolvesTheDefaultUserModel(): void { - $this->assertSame(User::class, $this->app['config']['auth.providers.users.model']); + $this->assertSame(User::class, $this->app->make('config')->string('auth.providers.users.model')); } } diff --git a/tests/Testbench/Fixtures/Providers/ChildServiceProvider.php b/tests/Testbench/Fixtures/Providers/ChildServiceProvider.php index 28518ac90..7deb52617 100644 --- a/tests/Testbench/Fixtures/Providers/ChildServiceProvider.php +++ b/tests/Testbench/Fixtures/Providers/ChildServiceProvider.php @@ -10,6 +10,6 @@ class ChildServiceProvider extends ServiceProvider { public function register(): void { - $this->app['child.loaded'] = true; + $this->app->instance('child.loaded', true); } } diff --git a/tests/Testbench/Fixtures/Providers/ParentServiceProvider.php b/tests/Testbench/Fixtures/Providers/ParentServiceProvider.php index 0f43ca002..5c88df00d 100644 --- a/tests/Testbench/Fixtures/Providers/ParentServiceProvider.php +++ b/tests/Testbench/Fixtures/Providers/ParentServiceProvider.php @@ -16,6 +16,6 @@ public function register(): void { parent::register(); - $this->app['parent.loaded'] = true; + $this->app->instance('parent.loaded', true); } } diff --git a/tests/Testbench/Foundation/ApplicationTest.php b/tests/Testbench/Foundation/ApplicationTest.php index e481295ed..aad91fd0c 100644 --- a/tests/Testbench/Foundation/ApplicationTest.php +++ b/tests/Testbench/Foundation/ApplicationTest.php @@ -59,11 +59,12 @@ public function itCanCreateAnApplication(): void $app = $testbench->createApplication(); $environment = Env::has('TESTBENCH_PACKAGE_TESTER') ? 'testing' : 'workbench'; + $applicationEnvironment = $app->make('env'); $this->assertInstanceOf(Application::class, $app); $this->assertSame('App\\', $app->getNamespace()); - $this->assertEquals($environment, $app['env']); - $this->assertSame($app['env'], $app['config']['app.env']); + $this->assertSame($environment, $applicationEnvironment); + $this->assertSame($applicationEnvironment, $app->make('config')->string('app.env')); $this->assertSame($environment, $app->environment()); $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER'), $app->runningUnitTests()); $this->assertFalse($testbench->isRunningTestCase()); @@ -75,11 +76,12 @@ public function itCanCreateAnApplicationUsingCreateHelper(): void $app = TestbenchApplication::create((string) default_skeleton_path()); $environment = Env::has('TESTBENCH_PACKAGE_TESTER') ? 'testing' : 'workbench'; + $applicationEnvironment = $app->make('env'); $this->assertInstanceOf(Application::class, $app); $this->assertSame('App\\', $app->getNamespace()); - $this->assertEquals($environment, $app['env']); - $this->assertSame($app['env'], $app['config']['app.env']); + $this->assertSame($environment, $applicationEnvironment); + $this->assertSame($applicationEnvironment, $app->make('config')->string('app.env')); $this->assertSame($environment, $app->environment()); $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER'), $app->runningUnitTests()); } @@ -94,11 +96,12 @@ public function itCanCreateAnApplicationUsingCreateFromConfigHelper(): void $app = TestbenchApplication::createFromConfig($config); $environment = Env::has('TESTBENCH_PACKAGE_TESTER') ? 'testing' : 'workbench'; + $applicationEnvironment = $app->make('env'); $this->assertInstanceOf(Application::class, $app); $this->assertSame('App\\', $app->getNamespace()); - $this->assertEquals($environment, $app['env']); - $this->assertSame($app['env'], $app['config']['app.env']); + $this->assertSame($environment, $applicationEnvironment); + $this->assertSame($applicationEnvironment, $app->make('config')->string('app.env')); $this->assertSame($environment, $app->environment()); $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER'), $app->runningUnitTests()); } diff --git a/tests/Testbench/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Testbench/Foundation/Bootstrap/CreateVendorSymlinkTest.php index c59fcaab2..68c1bff55 100644 --- a/tests/Testbench/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Testbench/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -69,7 +69,7 @@ public function itCanCreateVendorSymlink(): void (new CreateVendorSymlink($workingPath))->bootstrap($application); - $this->assertTrue($application['TESTBENCH_VENDOR_SYMLINK']); + $this->assertTrue($application->make('TESTBENCH_VENDOR_SYMLINK')); $this->assertSame($config, $application->make('config')); $application->terminate(); @@ -89,7 +89,7 @@ public function itCanSkipExistingVendorSymlink(): void (new CreateVendorSymlink($workingPath))->bootstrap($application); - $this->assertFalse($application['TESTBENCH_VENDOR_SYMLINK']); + $this->assertFalse($application->make('TESTBENCH_VENDOR_SYMLINK')); } #[Test] diff --git a/tests/Testbench/Integrations/ConfigTest.php b/tests/Testbench/Integrations/ConfigTest.php index a0ea08baf..324e97496 100644 --- a/tests/Testbench/Integrations/ConfigTest.php +++ b/tests/Testbench/Integrations/ConfigTest.php @@ -15,8 +15,10 @@ class ConfigTest extends TestCase #[Override] protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('database.default', 'testbench'); - $app['config']->set('database.connections.testbench', [ + $config = $app->make('config'); + + $config->set('database.default', 'testbench'); + $config->set('database.connections.testbench', [ 'driver' => 'sqlite', 'database' => ':memory:', ]); diff --git a/tests/Testbench/Integrations/EnvironmentVariablesTest.php b/tests/Testbench/Integrations/EnvironmentVariablesTest.php index eea35cb29..8a4bfbd65 100644 --- a/tests/Testbench/Integrations/EnvironmentVariablesTest.php +++ b/tests/Testbench/Integrations/EnvironmentVariablesTest.php @@ -19,7 +19,7 @@ class EnvironmentVariablesTest extends TestCase #[Override] protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('database.default', 'testing'); + $app->make('config')->set('database.default', 'testing'); } #[Override] diff --git a/tests/Testbench/Integrations/LoadUsingFrameworkConfigurationTest.php b/tests/Testbench/Integrations/LoadUsingFrameworkConfigurationTest.php index da68edfb4..ea033e034 100644 --- a/tests/Testbench/Integrations/LoadUsingFrameworkConfigurationTest.php +++ b/tests/Testbench/Integrations/LoadUsingFrameworkConfigurationTest.php @@ -19,7 +19,7 @@ class LoadUsingFrameworkConfigurationTest extends TestCase #[ResolvesHypervel('overrideHypervelConfiguration')] public function itCanLoadUsingFrameworkConfigurations(): void { - $this->assertSame(LoadConfiguration::class, $this->app[LoadConfiguration::class]::class); + $this->assertSame(LoadConfiguration::class, $this->app->make(LoadConfiguration::class)::class); $environment = Env::has('TESTBENCH_PACKAGE_TESTER') ? 'testing' : 'production'; diff --git a/tests/Testbench/Integrations/RouteTest.php b/tests/Testbench/Integrations/RouteTest.php index 29c9acb74..ec15b98be 100644 --- a/tests/Testbench/Integrations/RouteTest.php +++ b/tests/Testbench/Integrations/RouteTest.php @@ -100,7 +100,7 @@ public function itCanResolveDomainRoute(): void #[Test] public function itCanResolveNameRoutes(): void { - $this->app['router']->get('passthrough', fn () => route('bye'))->name('pass'); + $this->app->make(Router::class)->get('passthrough', fn () => route('bye'))->name('pass'); $response = $this->call('GET', route('pass')); @@ -111,7 +111,7 @@ public function itCanResolveNameRoutes(): void #[Test] public function itCanHandleRouteThrowingException(): void { - $this->app['router']->get('bad-route', fn () => throw new Exception('Route error!'))->name('bad'); + $this->app->make(Router::class)->get('bad-route', fn () => throw new Exception('Route error!'))->name('bad'); $response = $this->call('GET', route('bad')); diff --git a/tests/Testbench/TestCaseTest.php b/tests/Testbench/TestCaseTest.php index 852146550..e11bfb192 100644 --- a/tests/Testbench/TestCaseTest.php +++ b/tests/Testbench/TestCaseTest.php @@ -36,10 +36,10 @@ public function testDummy(): void $this->assertInstanceOf(Application::class, $app); $this->assertEquals('UTC', date_default_timezone_get()); - $this->assertEquals('testing', $app['env']); + $this->assertSame('testing', $app->make('env')); $this->assertSame('testing', $app->environment()); $this->assertTrue($app->runningUnitTests()); - $this->assertInstanceOf(ConfigRepository::class, $app['config']); + $this->assertInstanceOf(ConfigRepository::class, $app->make('config')); $this->assertInstanceOf(TestCaseContract::class, $testbench); $this->assertTrue($testbench->isRunningTestCase()); @@ -59,10 +59,10 @@ public function itCanCreateAContainer(): void $this->assertInstanceOf(Application::class, $app); $this->assertEquals('UTC', date_default_timezone_get()); - $this->assertEquals($environment, $app['env']); + $this->assertSame($environment, $app->make('env')); $this->assertSame($environment, $app->environment()); $this->assertSame(Env::has('TESTBENCH_PACKAGE_TESTER'), $app->runningUnitTests()); - $this->assertInstanceOf(ConfigRepository::class, $app['config']); + $this->assertInstanceOf(ConfigRepository::class, $app->make('config')); $this->assertFalse($container->isRunningTestCase()); $this->assertFalse($container->isRunningTestCaseUsingPest()); diff --git a/tests/Testbench/TestCaseTraitsTest.php b/tests/Testbench/TestCaseTraitsTest.php index e0377cef7..9981451fb 100644 --- a/tests/Testbench/TestCaseTraitsTest.php +++ b/tests/Testbench/TestCaseTraitsTest.php @@ -103,7 +103,7 @@ public function testAppIsAvailable(): void public function testPackageTestCaseRunsInTestingEnvironment(): void { - $this->assertSame('testing', $this->app['env']); + $this->assertSame('testing', $this->app->make('env')); $this->assertSame('testing', $this->app->environment()); $this->assertTrue($this->app->runningUnitTests()); } diff --git a/tests/Testbench/TestbenchTest.php b/tests/Testbench/TestbenchTest.php index 21d2daf75..f72a97f49 100644 --- a/tests/Testbench/TestbenchTest.php +++ b/tests/Testbench/TestbenchTest.php @@ -5,6 +5,7 @@ namespace Hypervel\Tests\Testbench; use Hypervel\Contracts\Bus\QueueingDispatcher; +use Hypervel\Contracts\Foundation\Application as ApplicationContract; use Hypervel\Queue\Queue; use Hypervel\Testbench\Attributes\DefineEnvironment; use Hypervel\Testbench\Concerns\Testing; @@ -32,14 +33,14 @@ public function itCanHandleCustomQueuePayload(): void $this->addToAssertionCount(1); } - protected function registerCustomQueuePayload(\Hypervel\Contracts\Foundation\Application $app): void + protected function registerCustomQueuePayload(ApplicationContract $app): void { - $app->bind('one.time.password', fn (): int => random_int(1, 10)); + $app->instance('one.time.password', random_int(1, 10)); Queue::createPayloadUsing(function () use ($app): array { $password = $app->make('one.time.password'); - $app->offsetUnset('one.time.password'); + $app->forgetInstance('one.time.password'); return ['password' => $password]; }); diff --git a/tests/Testing/Concerns/TestCachesTest.php b/tests/Testing/Concerns/TestCachesTest.php index b46cf33ea..8a1bb4f41 100644 --- a/tests/Testing/Concerns/TestCachesTest.php +++ b/tests/Testing/Concerns/TestCachesTest.php @@ -60,7 +60,7 @@ protected function tearDown(): void #[DataProvider('cachePrefixes')] public function testCachePrefixAppendsToken(string $prefix, string $token, string $expected): void { - Container::getInstance()['config']->set('cache.prefix', $prefix); + Container::getInstance()->make('config')->set('cache.prefix', $prefix); Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => $token); $this->assertSame($expected, $this->getParallelSafeCachePrefix()); @@ -87,11 +87,11 @@ public function testCachePrefixDoesNotReuseCustomPrefixFromPreviousCall(): void { Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '1'); - Container::getInstance()['config']->set('cache.prefix', 'custom_cache_'); + Container::getInstance()->make('config')->set('cache.prefix', 'custom_cache_'); $this->assertSame('custom_cache_test_1_', $this->getParallelSafeCachePrefix()); - Container::getInstance()['config']->set('cache.prefix', 'myapp_cache_'); + Container::getInstance()->make('config')->set('cache.prefix', 'myapp_cache_'); $this->assertSame('myapp_cache_test_1_', $this->getParallelSafeCachePrefix()); } @@ -99,7 +99,7 @@ public function testCachePrefixDoesNotReuseCustomPrefixFromPreviousCall(): void public function testCachePrefixDoesNotDoubleAppendToken(): void { Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '1'); - Container::getInstance()['config']->set('cache.prefix', 'myapp_cache_test_1_'); + Container::getInstance()->make('config')->set('cache.prefix', 'myapp_cache_test_1_'); $this->assertSame('myapp_cache_test_1_', $this->getParallelSafeCachePrefix()); } @@ -108,7 +108,7 @@ public function testSwitchToCachePrefixUpdatesConfig(): void { $this->switchToCachePrefix('new_prefix_'); - $this->assertSame('new_prefix_', Container::getInstance()['config']->get('cache.prefix')); + $this->assertSame('new_prefix_', Container::getInstance()->make('config')->get('cache.prefix')); } public function testBootTestCacheRegistersSetUpTestCaseCallback(): void @@ -142,7 +142,7 @@ public function testBootTestCacheSkipsIsolationIfOptedOut(): void Container::getInstance()->make(ParallelTesting::class)->callSetUpTestCaseCallbacks(new class {}); - $this->assertSame('myapp_cache_', Container::getInstance()['config']->get('cache.prefix')); + $this->assertSame('myapp_cache_', Container::getInstance()->make('config')->get('cache.prefix')); } finally { if ($hadValue) { $_SERVER['HYPERVEL_PARALLEL_TESTING_WITHOUT_CACHE'] = $original; @@ -157,15 +157,17 @@ public function testSwitchToCachePrefixDoesNotRemoveResolvedDrivers(): void $container = Container::getInstance(); $container->singleton('cache', fn ($app) => new CacheManager($app)); + $config = $container->make('config'); - $container['config']->set('cache.default', 'array'); - $container['config']->set('cache.stores.array', ['driver' => 'array']); + $config->set('cache.default', 'array'); + $config->set('cache.stores.array', ['driver' => 'array']); - $driver = $container['cache']->driver(); + $cache = $container->make('cache'); + $driver = $cache->driver(); $this->switchToCachePrefix('new_prefix_'); - $this->assertSame($driver, $container['cache']->driver()); + $this->assertSame($driver, $cache->driver()); } protected function getParallelSafeCachePrefix(): string @@ -190,7 +192,7 @@ protected function makeTestCachesInstance(): object return new class { use TestCaches; - public $app; + public Container $app; public function __construct() { diff --git a/tests/Testing/Concerns/TestViewsTest.php b/tests/Testing/Concerns/TestViewsTest.php index 30ba1219c..28b7e72c7 100644 --- a/tests/Testing/Concerns/TestViewsTest.php +++ b/tests/Testing/Concerns/TestViewsTest.php @@ -68,7 +68,7 @@ public function testCompiledViewPathTrimsTrailingSlash(): void { Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '3'); - Container::getInstance()['config']->set('view.compiled', '/path/to/compiled/views/'); + Container::getInstance()->make('config')->set('view.compiled', '/path/to/compiled/views/'); $this->assertSame('/path/to/compiled/views/test_3', $this->getCompiledViewPath()); } @@ -77,7 +77,7 @@ public function testCompiledViewPathWithDifferentToken(): void { Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '42'); - Container::getInstance()['config']->set('view.compiled', '/var/www/storage/views'); + Container::getInstance()->make('config')->set('view.compiled', '/var/www/storage/views'); $this->assertSame('/var/www/storage/views/test_42', $this->getCompiledViewPath()); } @@ -86,11 +86,11 @@ public function testCompiledViewPathDoesNotReuseCustomPathFromPreviousCall(): vo { Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '1'); - Container::getInstance()['config']->set('view.compiled', '/custom/views'); + Container::getInstance()->make('config')->set('view.compiled', '/custom/views'); $this->assertSame('/custom/views/test_1', $this->getCompiledViewPath()); - Container::getInstance()['config']->set('view.compiled', '/path/to/compiled/views'); + Container::getInstance()->make('config')->set('view.compiled', '/path/to/compiled/views'); $this->assertSame('/path/to/compiled/views/test_1', $this->getCompiledViewPath()); } @@ -98,14 +98,14 @@ public function testCompiledViewPathDoesNotReuseCustomPathFromPreviousCall(): vo public function testCompiledViewPathDoesNotDoubleAppendToken(): void { Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '1'); - Container::getInstance()['config']->set('view.compiled', '/path/to/compiled/views/test_1'); + Container::getInstance()->make('config')->set('view.compiled', '/path/to/compiled/views/test_1'); $this->assertSame('/path/to/compiled/views/test_1', $this->getCompiledViewPath()); } public function testCompiledViewPathReturnsNullWhenEmpty(): void { - Container::getInstance()['config']->set('view.compiled', ''); + Container::getInstance()->make('config')->set('view.compiled', ''); $this->assertNull($this->getCompiledViewPath()); } @@ -114,7 +114,7 @@ public function testSwitchToCompiledViewPathUpdatesConfig(): void { $this->switchToCompiledViewPath('/new/compiled/path'); - $this->assertSame('/new/compiled/path', Container::getInstance()['config']->get('view.compiled')); + $this->assertSame('/new/compiled/path', Container::getInstance()->make('config')->get('view.compiled')); } public function testSwitchToCompiledViewPathUpdatesCompilerCachePath(): void @@ -126,7 +126,7 @@ public function testSwitchToCompiledViewPathUpdatesCompilerCachePath(): void $this->switchToCompiledViewPath('/new/compiled/path'); - $this->assertSame('/new/compiled/path', $container['config']->get('view.compiled')); + $this->assertSame('/new/compiled/path', $container->make('config')->get('view.compiled')); $this->assertSame('/new/compiled/path', (new ReflectionProperty($compiler, 'cachePath'))->getValue($compiler)); } @@ -167,7 +167,7 @@ protected function makeTestViewsInstance(): object return new class { use TestViews; - public $app; + public Container $app; public function __construct() { diff --git a/tests/Testing/TestWithoutDatabaseParallelTest.php b/tests/Testing/TestWithoutDatabaseParallelTest.php index 6aa67e546..4dc201e55 100644 --- a/tests/Testing/TestWithoutDatabaseParallelTest.php +++ b/tests/Testing/TestWithoutDatabaseParallelTest.php @@ -18,7 +18,7 @@ protected function getPackageProviders(ApplicationContract $app): array protected function defineEnvironment(ApplicationContract $app): void { - $app['config']->set('database.default', null); + $app->make('config')->set('database.default', null); $serverKeys = [ 'HYPERVEL_PARALLEL_TESTING', @@ -47,6 +47,7 @@ protected function defineEnvironment(ApplicationContract $app): void public function testRunningParallelTestWithoutDatabaseShouldNotCrashOnDefaultConnection(): void { ParallelTesting::callSetUpProcessCallbacks(); - $this->assertTrue(true); + + $this->assertNull(config('database.default')); } }