Skip to content

Commit 72e213f

Browse files
committed
feat: implement workbench package and refactor current test cases
1 parent 15e3056 commit 72e213f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+538
-144
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ composer.lock
44
/phpunit.xml
55
.phpunit.result.cache
66
!tests/Foundation/fixtures/hyperf1/composer.lock
7-
tests/Foundation/fixtures/hyperf/runtime
87
tests/Http/fixtures

composer.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"autoload": {
2525
"psr-4": {
2626
"Illuminate\\Events\\": "src/event/illuminate/",
27+
"Workbench\\App\\": "src/testbench/workbench/app/",
2728
"Hypervel\\": "src/core/src/",
2829
"Hypervel\\Auth\\": "src/auth/src/",
2930
"Hypervel\\Broadcasting\\": "src/broadcasting/src/",
@@ -54,7 +55,8 @@
5455
"Hypervel\\Router\\": "src/router/src/",
5556
"Hypervel\\Session\\": "src/session/src/",
5657
"Hypervel\\Support\\": "src/support/src/",
57-
"Hypervel\\Telescope\\": "src/telescope/src/"
58+
"Hypervel\\Telescope\\": "src/telescope/src/",
59+
"Hypervel\\Testbench\\": "src/testbench/src/"
5860
},
5961
"files": [
6062
"src/auth/src/Functions.php",
@@ -152,7 +154,8 @@
152154
"hypervel/router": "self.version",
153155
"hypervel/session": "self.version",
154156
"hypervel/support": "self.version",
155-
"hypervel/telescope": "self.version"
157+
"hypervel/telescope": "self.version",
158+
"hypervel/testbench": "self.version"
156159
},
157160
"suggest": {
158161
"hyperf/redis": "Required to use redis driver. (^3.1).",
@@ -186,7 +189,8 @@
186189
"phpstan/phpstan": "^1.11.5",
187190
"phpunit/phpunit": "^10.0.7",
188191
"pusher/pusher-php-server": "^7.2",
189-
"swoole/ide-helper": "~5.1.0"
192+
"swoole/ide-helper": "~5.1.0",
193+
"symfony/yaml": "^7.3"
190194
},
191195
"config": {
192196
"sort-packages": true

src/foundation/src/Providers/FoundationServiceProvider.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ protected function overrideHyperfConfigs(): void
9797
$configs = [
9898
'app_name' => $this->config->get('app.name'),
9999
'app_env' => $this->config->get('app.env'),
100-
'scan_cacheable' => $this->config->get('app.scan_cacheable'),
101100
StdoutLoggerInterface::class . '.log_level' => $this->config->get('app.stdout_log_level'),
102101
'translation.locale' => $this->config->get('app.locale'),
103102
'translation.fallback_locale' => $this->config->get('app.fallback_locale'),

src/foundation/src/Testing/Traits/CanConfigureMigrationCommands.php

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ trait CanConfigureMigrationCommands
1010
{
1111
/**
1212
* The parameters that should be used when running "migrate:fresh".
13-
*
14-
* @return array
1513
*/
16-
protected function migrateFreshUsing()
14+
protected function migrateFreshUsing(): array
1715
{
1816
$seeder = $this->seeder();
1917
$connection = $this->app
@@ -31,30 +29,24 @@ protected function migrateFreshUsing()
3129

3230
/**
3331
* Determine if views should be dropped when refreshing the database.
34-
*
35-
* @return bool
3632
*/
37-
protected function shouldDropViews()
33+
protected function shouldDropViews(): bool
3834
{
3935
return property_exists($this, 'dropViews') ? $this->dropViews : false;
4036
}
4137

4238
/**
4339
* Determine if the seed task should be run when refreshing the database.
44-
*
45-
* @return bool
4640
*/
47-
protected function shouldSeed()
41+
protected function shouldSeed(): bool
4842
{
4943
return property_exists($this, 'seed') ? $this->seed : false;
5044
}
5145

5246
/**
5347
* Determine the specific seeder class that should be used when refreshing the database.
54-
*
55-
* @return mixed
5648
*/
57-
protected function seeder()
49+
protected function seeder(): mixed
5850
{
5951
return property_exists($this, 'seeder') ? $this->seeder : false;
6052
}

src/testbench/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
workbench/.env
2+
workbench/composer.lock
3+
workbench/runtime

src/testbench/bin/testbench-sync

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
$workingPath = getcwd();
5+
6+
require "{$workingPath}/vendor/autoload.php";
7+
8+
$files = new Hypervel\Filesystem\Filesystem();
9+
$files->copy("{$workingPath}/vendor/hypervel/testbench/testbench.yaml", "{$workingPath}/testbench.yaml");
10+
11+
Hypervel\Support\Collection::make([
12+
...$files->allFiles("{$workingPath}/vendor/hypervel/testbench/workbench/app/"),
13+
])->flatten()
14+
->filter(static fn ($file) => is_file($file))
15+
->each(static function ($file) use ($files, $workingPath) {
16+
$filename = $workingPath . Hypervel\Support\Str::after((string) $file, "{$workingPath}/vendor/hypervel/testbench/workbench");
17+
$files->ensureDirectoryExists(Hypervel\Support\Str::before($filename, basename($filename)));
18+
$files->copy($file, $filename);
19+
});
20+
21+
Hypervel\Support\Collection::make([
22+
...$files->allFiles("{$workingPath}/vendor/hypervel/testbench/workbench/config/"),
23+
...$files->allFiles("{$workingPath}/vendor/hypervel/testbench/workbench/database/"),
24+
...$files->allFiles("{$workingPath}/vendor/hypervel/testbench/workbench/lang/"),
25+
...$files->allFiles("{$workingPath}/vendor/hypervel/testbench/workbench/routes/"),
26+
...$files->allFiles("{$workingPath}/vendor/hypervel/testbench/workbench/resources/"),
27+
])->flatten()
28+
->filter(static fn ($file) => is_file($file))
29+
->each(static function ($file) use ($files, $workingPath) {
30+
$filename = $workingPath . Hypervel\Support\Str::after((string) $file, "{$workingPath}/vendor/hypervel/testbench/workbench");
31+
$files->ensureDirectoryExists(Hypervel\Support\Str::before($filename, basename($filename)));
32+
$files->copy($file, $filename);
33+
});

src/testbench/composer.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "hypervel/testbench",
3+
"description": "The testbench package for Hypervel.",
4+
"license": "MIT",
5+
"keywords": [
6+
"php",
7+
"hyperf",
8+
"testbench",
9+
"swoole",
10+
"hypervel"
11+
],
12+
"support": {
13+
"issues": "https://github.com/hypervel/components/issues",
14+
"source": "https://github.com/hypervel/components"
15+
},
16+
"authors": [
17+
{
18+
"name": "Albert Chen",
19+
"email": "albert@hypervel.org"
20+
}
21+
],
22+
"require": {
23+
"php": "^8.2",
24+
"hypervel/framework": "^0.1",
25+
"mockery/mockery": "^1.6.10",
26+
"phpunit/phpunit": "^10.0.7",
27+
"symfony/yaml": "^7.3",
28+
"vlucas/phpdotenv": "^5.6.1"
29+
},
30+
"autoload": {
31+
"psr-4": {
32+
"Hypervel\\Testbench\\": "src/",
33+
"Workbench\\App\\": "workbench/app/"
34+
}
35+
},
36+
"extra": {
37+
"branch-alias": {
38+
"dev-main": "0.1-dev"
39+
}
40+
},
41+
"config": {
42+
"sort-packages": true
43+
},
44+
"bin": [
45+
"bin/testbench-sync"
46+
],
47+
"scripts": {
48+
"sync": "@php bin/testbench-sync"
49+
},
50+
"minimum-stability": "dev"
51+
}

src/testbench/src/Bootstrapper.php

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hypervel\Testbench;
6+
7+
use Hyperf\Collection\LazyCollection;
8+
use Hypervel\Filesystem\Filesystem;
9+
use Hypervel\Foundation\ClassLoader;
10+
use Hypervel\Foundation\Testing\TestScanHandler;
11+
use Symfony\Component\Yaml\Yaml;
12+
13+
use function Hypervel\Filesystem\join_paths;
14+
15+
class Bootstrapper
16+
{
17+
protected static $config = [];
18+
19+
protected static ?Filesystem $filesystem = null;
20+
21+
public static function bootstrap(): void
22+
{
23+
static::loadConfigFromYaml(
24+
$workingPath = defined('TESTBENCH_WORKING_PATH') ? TESTBENCH_WORKING_PATH : dirname(__DIR__)
25+
);
26+
27+
$basePath = "{$workingPath}/workbench";
28+
if (static::$config['hypervel'] ?? null) {
29+
$basePath = static::$config['hypervel'];
30+
}
31+
32+
! defined('BASE_PATH') && define('BASE_PATH', $basePath);
33+
! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);
34+
35+
static::generateEnv();
36+
static::generateComposerLock();
37+
static::registerPurgeFiles();
38+
39+
ClassLoader::init(null, null, new TestScanHandler());
40+
}
41+
42+
public static function getConfig(): array
43+
{
44+
return static::$config;
45+
}
46+
47+
protected static function getFilesystem(): Filesystem
48+
{
49+
if (static::$filesystem) {
50+
return static::$filesystem;
51+
}
52+
53+
return static::$filesystem = new Filesystem();
54+
}
55+
56+
protected static function generateComposerLock(): void
57+
{
58+
$content = [
59+
'packages' => [
60+
[
61+
'name' => 'hypervel-testbench',
62+
'extra' => [
63+
'hypervel' => [
64+
'config' => static::getConfigProviders(),
65+
'providers' => static::$config['providers'] ?? [],
66+
'dont-discover' => static::$config['dont-discover'] ?? [],
67+
],
68+
],
69+
],
70+
],
71+
'packages-dev' => [],
72+
];
73+
74+
static::getFilesystem()->replace(
75+
BASE_PATH . '/composer.lock',
76+
json_encode($content, JSON_PRETTY_PRINT)
77+
);
78+
}
79+
80+
protected static function loadConfigFromYaml(string $workingPath, ?string $filename = 'testbench.yaml', array $defaults = []): void
81+
{
82+
$filename = LazyCollection::make(static function () use ($filename) {
83+
yield $filename;
84+
yield "{$filename}.example";
85+
yield "{$filename}.dist";
86+
})->map(static function ($file) use ($workingPath) {
87+
return str_contains($file, DIRECTORY_SEPARATOR) ? $file : join_paths($workingPath, $file);
88+
})->filter(static fn ($file) => is_file($file))
89+
->first();
90+
91+
if (is_null($filename)) {
92+
return;
93+
}
94+
95+
static::$config = Yaml::parseFile($filename) ?? [];
96+
}
97+
98+
protected static function generateEnv(): void
99+
{
100+
if (! $env = static::$config['env'] ?? []) {
101+
return;
102+
}
103+
104+
static::getFilesystem()->replace(
105+
join_paths(BASE_PATH, '/.env'),
106+
implode(PHP_EOL, $env)
107+
);
108+
}
109+
110+
protected static function getConfigProviders(): array
111+
{
112+
ConfigProviderRegister::add(
113+
static::$config['config-providers'] ?? []
114+
);
115+
116+
return ConfigProviderRegister::get();
117+
}
118+
119+
protected static function registerPurgeFiles(): void
120+
{
121+
$purge = static::$config['purge'] ?? [];
122+
$files = $purge['files'] ?? [];
123+
$directories = $purge['directories'] ?? [];
124+
125+
if (! $files && ! $directories) {
126+
return;
127+
}
128+
129+
register_shutdown_function(function () use ($files, $directories) {
130+
$filesystem = static::getFilesystem();
131+
foreach ($files as $file) {
132+
if (! $filesystem->exists($file = BASE_PATH . "/{$file}")) {
133+
continue;
134+
}
135+
$filesystem->delete($file);
136+
}
137+
138+
foreach ($directories as $directory) {
139+
if (! $filesystem->exists($directory = BASE_PATH . "/{$directory}")) {
140+
continue;
141+
}
142+
$filesystem->deleteDirectory($directory);
143+
}
144+
});
145+
}
146+
}

tests/Foundation/Testing/BootstrapConfigProvider.php renamed to src/testbench/src/ConfigProviderRegister.php

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
declare(strict_types=1);
44

5-
namespace Hypervel\Tests\Foundation\Testing;
5+
namespace Hypervel\Testbench;
66

7-
class BootstrapConfigProvider
7+
use Hyperf\Collection\Arr;
8+
9+
class ConfigProviderRegister
810
{
911
protected static $configProviders = [
1012
\Hyperf\Command\ConfigProvider::class,
@@ -55,9 +57,30 @@ class BootstrapConfigProvider
5557
public static function get(): array
5658
{
5759
if (class_exists($devtoolClass = \Hyperf\Devtool\ConfigProvider::class)) {
58-
return array_merge(self::$configProviders, [$devtoolClass]);
60+
return array_merge(static::$configProviders, [$devtoolClass]);
5961
}
6062

61-
return self::$configProviders;
63+
return static::$configProviders;
64+
}
65+
66+
public static function filter(callable $callback): array
67+
{
68+
return static::$configProviders = array_filter(static::get(), $callback);
69+
}
70+
71+
public static function add(array|string $providers): void
72+
{
73+
static::$configProviders = array_merge(
74+
static::$configProviders,
75+
Arr::wrap($providers)
76+
);
77+
}
78+
79+
public static function except(array|string $providers): void
80+
{
81+
static::$configProviders = array_diff(
82+
static::$configProviders,
83+
Arr::wrap($providers)
84+
);
6285
}
6386
}

0 commit comments

Comments
 (0)