Skip to content

Commit

Permalink
Merge branch '9.x' into 10.x
Browse files Browse the repository at this point in the history
  • Loading branch information
crynobone committed Sep 24, 2024
2 parents 0f5cd57 + a293869 commit 4036777
Show file tree
Hide file tree
Showing 25 changed files with 610 additions and 50 deletions.
8 changes: 0 additions & 8 deletions .github/workflows/parallel-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,3 @@ jobs:
run: ./testbench package:test --parallel --exclude-group commander,without-parallel,database,session --no-coverage
env:
RAY_ENABLED: false
if: matrix.dependencies == 'highest'

- name: Execute tests (without deprecations)
run: ./testbench package:test --parallel --exclude-group commander,without-parallel,database,session,deprecations --no-coverage
env:
RAY_ENABLED: false
TESTBENCH_CONVERT_DEPRECATIONS_TO_EXCEPTIONS: false
if: matrix.dependencies != 'highest'
37 changes: 37 additions & 0 deletions CHANGELOG-8.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,43 @@

This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`.

## 8.28.1

Released: 2024-09-24

### Fixes

* Fixes compatibility with PHPUnit 10.3.

## 8.28.0

Released: 2024-09-23

### Added

* Added `markTestSkippedWhen()` and `markTestSkippedUnless()` assertion helper to conditionally handle `markTestSkipped()`.
* Added `Orchestra\Testbench\default_migration_path()` helper function.
* Added `Orchestra\Testbench\laravel_vendor_exists()` helper function.
* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #233.

### Changes

* Allow Testbench to delete `vendor` symlink directory if it was created while running tests.

### Fixes

* Fixes `view.paths` configuration not being updated to include `workbench/resources/views` due to IoC booting sequence.

### Deprecated

* Deprecated `Orchestra\Testbench\laravel_migration_path()`, use `default_migration_path()` instead.

<!--
#### New Contributors
* @BlackLanzer made their first contribution in https://github.com/orchestral/testbench-core/pull/233
-->

## 8.27.0

Released: 2024-08-26
Expand Down
38 changes: 38 additions & 0 deletions CHANGELOG-9.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,44 @@

This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`.

## 9.5.0

Released: 2024-09-23

### Added

* Added `Orchestra\Testbench\Attributes\RequiresDatabase` attribute class.
* Added `markTestSkippedWhen()` and `markTestSkippedUnless()` assertion helper to conditionally handle `markTestSkipped()`.
* Added `Orchestra\Testbench\default_migration_path()` helper function.
* Added `Orchestra\Testbench\laravel_vendor_exists()` helper function.
* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #233.

### Changes

* Allow Testbench to delete `vendor` symlink directory if it was created while running tests.

### Fixes

* Fixes `view.paths` configuration not being updated to include `workbench/resources/views` due to IoC booting sequence.

### Deprecated

* Deprecated `Orchestra\Testbench\laravel_migration_path()`, use `default_migration_path()` instead.

<!--
#### New Contributors
* @BlackLanzer made their first contribution in https://github.com/orchestral/testbench-core/pull/233
-->

## 9.4.1

Released: 2024-09-12

### Changes

* Add `concurrency.php` configuration based on Laravel Framework 11.23.

## 9.4.0

Released: 2024-08-26
Expand Down
20 changes: 20 additions & 0 deletions laravel/config/concurrency.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

return [

/*
|--------------------------------------------------------------------------
| Default Concurrency Driver
|--------------------------------------------------------------------------
|
| This option determines the default concurrency driver that will be used
| by Laravel's concurrency functions. By default, concurrent work will
| be sent to isolated PHP processes which will return their results.
|
| Supported: "process", "fork", "sync"
|
*/

'driver' => env('CONCURRENCY_DRIVER', 'process'),

];
92 changes: 92 additions & 0 deletions src/Attributes/RequiresDatabase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Orchestra\Testbench\Attributes;

use Attribute;
use Closure;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;
use Orchestra\Testbench\Contracts\Attributes\Actionable as ActionableContract;

#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
final class RequiresDatabase implements ActionableContract
{
/**
* Construct a new attribute.
*
* @param string $driver
* @param string|null $versionRequirement
* @param string|null $connection
* @param bool|null $default
*/
public function __construct(
public array|string $driver,
public ?string $versionRequirement = null,
public ?string $connection = null,
public ?bool $default = null
) {
if (\is_null($connection) && \is_string($driver)) {
$this->default = true;
}

if (\is_array($driver) && $default === true) {
throw new InvalidArgumentException('Unable to validate default connection when given an array of database drivers');
}
}

/**
* Handle the attribute.
*
* @param \Illuminate\Foundation\Application $app
* @param \Closure(string, array<int, mixed>):void $action
* @return void
*/
public function handle($app, Closure $action): void
{
$connection = DB::connection($this->connection);

if (
($this->default ?? false) === true
&& \is_string($this->driver)
&& $connection->getDriverName() !== $this->driver
) {
\call_user_func($action, 'markTestSkipped', [\sprintf('Requires %s to configured for "%s" database connection', $this->driver, $connection->getName())]);

return;
}

$drivers = Collection::make(
Arr::wrap($this->driver)
)->filter(fn ($driver) => $driver === $connection->getDriverName());

if ($drivers->isEmpty()) {
\call_user_func(
$action,
'markTestSkipped',
[\sprintf('Requires [%s] to be configured for "%s" database connection', Arr::join(Arr::wrap($this->driver), '/'), $connection->getName())]
);

return;
}

if (
is_string($this->driver)
&& ! \is_null($this->versionRequirement)
&& preg_match('/(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m', $this->versionRequirement, $matches)
) {
if (empty($matches['operator'])) {
$matches['operator'] = '>=';
}

if (! version_compare($connection->getServerVersion(), $matches['version'], $matches['operator'])) {
\call_user_func(
$action,
'markTestSkipped',
[\sprintf('Requires %s:%s to be configured for "%s" database connection', $this->driver, $this->versionRequirement, $connection->getName())]
);
}
}
}
}
4 changes: 2 additions & 2 deletions src/Attributes/WithMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Illuminate\Support\Collection;
use Orchestra\Testbench\Contracts\Attributes\Invokable as InvokableContract;

use function Orchestra\Testbench\laravel_migration_path;
use function Orchestra\Testbench\default_migration_path;
use function Orchestra\Testbench\load_migration_paths;

#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
Expand Down Expand Up @@ -38,7 +38,7 @@ public function __invoke($app): void
{
/** @var array<int, string> $types */
$types = Collection::make($this->types)
->transform(static fn ($type) => laravel_migration_path($type !== 'laravel' ? $type : null))
->transform(static fn ($type) => default_migration_path($type !== 'laravel' ? $type : null))
->all();

load_migration_paths($app, $types);
Expand Down
36 changes: 36 additions & 0 deletions src/Concerns/HandlesAssertions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Orchestra\Testbench\Concerns;

trait HandlesAssertions
{
/**
* Mark the test as skipped when condition is not equivalent to true.
*
* @param (\Closure($this): bool)|bool|null $condition
* @param string $message
* @return void
*/
protected function markTestSkippedUnless($condition, string $message): void
{
/** @phpstan-ignore argument.type */
if (! value($condition)) {
$this->markTestSkipped($message);
}
}

/**
* Mark the test as skipped when condition is equivalent to true.
*
* @param (\Closure($this): bool)|bool|null $condition
* @param string $message
* @return void
*/
protected function markTestSkippedWhen($condition, string $message): void
{
/** @phpstan-ignore argument.type */
if (value($condition)) {
$this->markTestSkipped($message);
}
}
}
6 changes: 6 additions & 0 deletions src/Concerns/HandlesDatabases.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Closure;
use Illuminate\Database\Events\DatabaseRefreshed;
use Orchestra\Testbench\Attributes\DefineDatabase;
use Orchestra\Testbench\Attributes\RequiresDatabase;
use Orchestra\Testbench\Attributes\WithMigration;
use Orchestra\Testbench\Exceptions\ApplicationNotAvailableException;
use Orchestra\Testbench\Features\TestingFeature;
Expand All @@ -27,6 +28,11 @@ protected function setUpDatabaseRequirements(Closure $callback): void
throw ApplicationNotAvailableException::make(__METHOD__);
}

TestingFeature::run(
testCase: $this,
attribute: fn () => $this->parseTestMethodAttributes($app, RequiresDatabase::class),
);

$app['events']->listen(DatabaseRefreshed::class, function () {
$this->defineDatabaseMigrationsAfterDatabaseRefreshed();
});
Expand Down
4 changes: 2 additions & 2 deletions src/Concerns/InteractsWithMigrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Orchestra\Testbench\Database\MigrateProcessor;
use Orchestra\Testbench\Exceptions\ApplicationNotAvailableException;

use function Orchestra\Testbench\laravel_migration_path;
use function Orchestra\Testbench\default_migration_path;
use function Orchestra\Testbench\load_migration_paths;

/**
Expand Down Expand Up @@ -130,7 +130,7 @@ protected function loadLaravelMigrations(array|string $database = []): void
}

$options = $this->resolveLaravelMigrationsOptions($database);
$options['--path'] = laravel_migration_path();
$options['--path'] = default_migration_path();
$options['--realpath'] = true;

$migrator = new MigrateProcessor($this, $this->resolveLaravelMigrationsOptions($options));
Expand Down
1 change: 1 addition & 0 deletions src/Concerns/Testing.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ trait Testing
use ApplicationTestingHooks;
use CreatesApplication;
use HandlesAnnotations;
use HandlesAssertions;
use HandlesAttributes;
use HandlesDatabases;
use HandlesRoutes;
Expand Down
6 changes: 3 additions & 3 deletions src/Concerns/WithLaravelMigrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Illuminate\Foundation\Testing\RefreshDatabaseState;

use function Orchestra\Testbench\after_resolving;
use function Orchestra\Testbench\laravel_migration_path;
use function Orchestra\Testbench\default_migration_path;

trait WithLaravelMigrations
{
Expand All @@ -23,7 +23,7 @@ protected function setUpWithLaravelMigrations(): void
/** @var bool $loadLaravelMigrations */
$loadLaravelMigrations = static::cachedConfigurationForWorkbench()->getWorkbenchAttributes()['install'] ?? false;

if (! ($loadLaravelMigrations && is_dir(laravel_migration_path()))) {
if (! ($loadLaravelMigrations && is_dir(default_migration_path()))) {
return;
}

Expand All @@ -34,7 +34,7 @@ protected function setUpWithLaravelMigrations(): void
) {
after_resolving($this->app, 'migrator', static function ($migrator, $app) {
/** @var \Illuminate\Database\Migrations\Migrator $migrator */
$migrator->path(laravel_migration_path());
$migrator->path(default_migration_path());
});
} else {
$this->loadLaravelMigrations();
Expand Down
Loading

0 comments on commit 4036777

Please sign in to comment.