Skip to content

Commit d5cdbe9

Browse files
authored
fix: correct generated namespace (#8)
* wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> --------- Signed-off-by: Mior Muhammad Zaki <[email protected]>
1 parent 36c6840 commit d5cdbe9

File tree

10 files changed

+388
-11
lines changed

10 files changed

+388
-11
lines changed

src/DevToolServiceProvider.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,7 @@ protected function registerResourceCommand()
149149
*/
150150
public function boot()
151151
{
152-
if (
153-
$this->app->runningInConsole()
154-
&& \defined('TESTBENCH_WORKING_PATH')
155-
) {
152+
if ($this->app->runningInConsole() && defined('TESTBENCH_CORE')) {
156153
tap($this->app->make('events'), function (EventDispatcher $event) {
157154
$event->listen(InstallStarted::class, [Listeners\InstallingWorkbench::class, 'handle']);
158155
$event->listen(InstallEnded::class, [Listeners\InstalledWorkbench::class, 'handle']);

src/Listeners/InstalledWorkbench.php

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ public function handle(InstallEnded $event)
5050
force: $force,
5151
))->handle(
5252
join_paths($workingDirectory, 'base-resource.stub'),
53-
Workbench::path(['app', 'Nova', 'Resource.php'])
53+
$baseResource = Workbench::path(['app', 'Nova', 'Resource.php'])
5454
);
5555

56+
$this->replaceInFile($baseResource);
57+
5658
(new GeneratesFile(
5759
filesystem: $this->files,
5860
components: $event->components,
@@ -62,22 +64,94 @@ public function handle(InstallEnded $event)
6264
$userResource = Workbench::path(['app', 'Nova', 'User.php'])
6365
);
6466

67+
$this->replaceInFile($userResource);
68+
6569
(new GeneratesFile(
6670
filesystem: $this->files,
6771
components: $event->components,
6872
force: $force,
6973
))->handle(
7074
join_paths($workingDirectory, 'NovaServiceProvider.stub'),
71-
Workbench::path(['app', 'Providers', 'NovaServiceProvider.php'])
75+
$serviceProvider = Workbench::path(['app', 'Providers', 'NovaServiceProvider.php'])
7276
);
7377

78+
$this->replaceInFile($serviceProvider);
79+
7480
Collection::make([
7581
Workbench::path(['app', '.gitkeep']),
82+
Workbench::path(['app', 'Models', '.gitkeep']),
7683
Workbench::path(['app', 'Nova', '.gitkeep']),
7784
Workbench::path(['app', 'Providers', '.gitkeep']),
7885
Workbench::path(['database', 'seeders', '.gitkeep']),
7986
])->each(function ($file) {
8087
$this->files->delete($file);
8188
});
8289
}
90+
91+
/**
92+
* Replace strings in given file.
93+
*/
94+
protected function replaceInFile(string $filename): void
95+
{
96+
$workbenchAppNamespacePrefix = rtrim(Workbench::detectNamespace('app') ?? 'Workbench\App\\', '\\');
97+
$workbenchFactoriesNamespacePrefix = rtrim(Workbench::detectNamespace('database/factories') ?? 'Workbench\Database\Factories\\', '\\');
98+
$workbenchSeederNamespacePrefix = rtrim(Workbench::detectNamespace('database/seeders') ?? 'Workbench\Database\Seeders\\', '\\');
99+
100+
$serviceProvider = sprintf('%s\Providers\WorkbenchServiceProvider', $workbenchAppNamespacePrefix);
101+
$databaseSeeder = sprintf('%s\DatabaseSeeder', $workbenchSeederNamespacePrefix);
102+
$userModel = sprintf('%s\Models\User', $workbenchAppNamespacePrefix);
103+
$userFactory = sprintf('%s\UserFactory', $workbenchFactoriesNamespacePrefix);
104+
105+
$this->files->replaceInFile(
106+
[
107+
'{{WorkbenchAppNamespace}}',
108+
'{{ WorkbenchAppNamespace }}',
109+
'{{WorkbenchFactoryNamespace}}',
110+
'{{ WorkbenchFactoryNamespace }}',
111+
'{{WorkbenchSeederNamespace}}',
112+
'{{ WorkbenchSeederNamespace }}',
113+
114+
'{{WorkbenchServiceProvider}}',
115+
'{{ WorkbenchServiceProvider }}',
116+
'Workbench\App\Providers\WorkbenchServiceProvider',
117+
118+
'{{WorkbenchDatabaseSeeder}}',
119+
'{{ WorkbenchDatabaseSeeder }}',
120+
'Workbench\Database\Seeders\DatabaseSeeder',
121+
122+
'{{WorkbenchUserModel}}',
123+
'{{ WorkbenchUserModel }}',
124+
'Workbench\App\Models\User',
125+
126+
'{{WorkbenchUserFactory}}',
127+
'{{ WorkbenchUserFactory }}',
128+
'Workbench\Database\Factories\UserFactory',
129+
],
130+
[
131+
$workbenchAppNamespacePrefix,
132+
$workbenchAppNamespacePrefix,
133+
$workbenchFactoriesNamespacePrefix,
134+
$workbenchFactoriesNamespacePrefix,
135+
$workbenchSeederNamespacePrefix,
136+
$workbenchSeederNamespacePrefix,
137+
138+
$serviceProvider,
139+
$serviceProvider,
140+
$serviceProvider,
141+
142+
$databaseSeeder,
143+
$databaseSeeder,
144+
$databaseSeeder,
145+
146+
$userModel,
147+
$userModel,
148+
$userModel,
149+
150+
$userFactory,
151+
$userFactory,
152+
$userFactory,
153+
],
154+
$filename
155+
);
156+
}
83157
}

stubs/NovaServiceProvider.stub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Workbench\App\Providers;
3+
namespace {{WorkbenchAppNamespace}}\Providers;
44

55
use Illuminate\Support\Facades\Gate;
66
use Laravel\Fortify\Features;

stubs/base-resource.stub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Workbench\App\Nova;
3+
namespace {{WorkbenchAppNamespace}}\Nova;
44

55
use Illuminate\Contracts\Database\Eloquent\Builder;
66
use Laravel\Nova\Http\Requests\NovaRequest;

stubs/user-resource.stub

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Workbench\App\Nova;
3+
namespace {{WorkbenchAppNamespace}}\Nova;
44

55
use Illuminate\Http\Request;
66
use Laravel\Nova\Auth\PasswordValidationRules;
@@ -16,9 +16,9 @@ class User extends Resource
1616
/**
1717
* The model the resource corresponds to.
1818
*
19-
* @var class-string<\Workbench\App\Models\User>
19+
* @var class-string<\{{WorkbenchAppNamespace}}\Models\User>
2020
*/
21-
public static $model = \Workbench\App\Models\User::class;
21+
public static $model = \{{WorkbenchAppNamespace}}\Models\User::class;
2222

2323
/**
2424
* The single value that should be used to represent the resource when being displayed.

tests/Command/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
./*_stubs/*

tests/Command/CommandTestCase.php

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
<?php
2+
3+
namespace Tests\Command;
4+
5+
use Database\Seeders\DatabaseSeeder;
6+
use Illuminate\Filesystem\Filesystem;
7+
use Laravel\Nova\DevTool\DevToolServiceProvider;
8+
use Orchestra\Canvas\LaravelServiceProvider;
9+
use Orchestra\Testbench\Foundation\Config;
10+
use Orchestra\Testbench\Foundation\TestbenchServiceProvider;
11+
use Orchestra\Workbench\Workbench;
12+
use Orchestra\Workbench\WorkbenchServiceProvider;
13+
use RuntimeException;
14+
use Workbench\Database\Seeders\DatabaseSeeder as WorkbenchDatabaseSeeder;
15+
16+
use function Orchestra\Testbench\default_skeleton_path;
17+
use function Orchestra\Testbench\join_paths;
18+
19+
abstract class CommandTestCase extends \Orchestra\Testbench\TestCase
20+
{
21+
/** {@inheritDoc} */
22+
#[\Override]
23+
protected function setUp(): void
24+
{
25+
$filesystem = new Filesystem;
26+
$workingPath = static::stubWorkingPath();
27+
28+
$this->beforeApplicationDestroyed(function () use ($filesystem, $workingPath) {
29+
$filesystem->deleteDirectory($workingPath);
30+
unset($_ENV['TESTBENCH_WORKING_PATH']);
31+
Workbench::flush();
32+
});
33+
34+
$_ENV['TESTBENCH_WORKING_PATH'] = $workingPath;
35+
$filesystem->ensureDirectoryExists($workingPath);
36+
$filesystem->copy(join_paths(__DIR__, 'stubs', 'composer.json'), join_paths($workingPath, 'composer.json'));
37+
$filesystem->copy(join_paths(__DIR__, 'stubs', 'phpunit.xml.dist'), join_paths($workingPath, 'phpunit.xml.dist'));
38+
39+
parent::setUp();
40+
}
41+
42+
/** {@inheritDoc} */
43+
#[\Override]
44+
protected function getPackageProviders($app)
45+
{
46+
return [
47+
TestbenchServiceProvider::class,
48+
WorkbenchServiceProvider::class,
49+
LaravelServiceProvider::class,
50+
DevToolServiceProvider::class,
51+
];
52+
}
53+
54+
protected function defineEnvironment($app)
55+
{
56+
if (! defined('TESTBENCH_CORE')) {
57+
define('TESTBENCH_CORE', true);
58+
}
59+
}
60+
61+
/**
62+
* Assert `workbench:devtool` or `workbench:install --devtool` command executed.
63+
*/
64+
protected function assertCommandExecutedWithDevTool(bool $prefix = true): void
65+
{
66+
$workingPath = static::stubWorkingPath();
67+
68+
$this->assertDirectoryExists(join_paths($workingPath, 'workbench', 'app', 'Models'));
69+
$this->assertDirectoryExists(join_paths($workingPath, 'workbench', 'app', 'Providers'));
70+
$this->assertDirectoryExists(join_paths($workingPath, 'workbench', 'database', 'factories'));
71+
$this->assertDirectoryExists(join_paths($workingPath, 'workbench', 'database', 'seeders'));
72+
73+
$this->assertFileContains([
74+
sprintf('namespace %sModels;', $prefix ? 'Workbench\App\\' : 'App\\'),
75+
'class User extends Authenticatable',
76+
], join_paths($workingPath, 'workbench', 'app', 'Models', 'User.php'));
77+
78+
$this->assertFileContains([
79+
sprintf('namespace %sNova;', $prefix ? 'Workbench\App\\' : 'App\\'),
80+
'abstract class Resource extends NovaResource',
81+
], join_paths($workingPath, 'workbench', 'app', 'Nova', 'Resource.php'));
82+
83+
$this->assertFileContains([
84+
sprintf('namespace %sNova;', $prefix ? 'Workbench\App\\' : 'App\\'),
85+
'class User extends Resource',
86+
sprintf('public static $model = \%sModels\User::class;', $prefix ? 'Workbench\App\\' : 'App\\'),
87+
], join_paths($workingPath, 'workbench', 'app', 'Nova', 'User.php'));
88+
89+
$this->assertFileContains([
90+
sprintf('namespace %sProviders;', $prefix ? 'Workbench\App\\' : 'App\\'),
91+
'class NovaServiceProvider extends NovaApplicationServiceProvider',
92+
], join_paths($workingPath, 'workbench', 'app', 'Providers', 'NovaServiceProvider.php'));
93+
94+
$this->assertFileContains([
95+
sprintf('namespace %sProviders;', $prefix ? 'Workbench\App\\' : 'App\\'),
96+
'class WorkbenchServiceProvider extends ServiceProvider',
97+
], join_paths($workingPath, 'workbench', 'app', 'Providers', 'WorkbenchServiceProvider.php'));
98+
99+
$this->assertFileContains([
100+
sprintf('namespace %sFactories;', $prefix ? 'Workbench\Database\\' : 'Database\\'),
101+
sprintf('use %sModels\User;', $prefix ? 'Workbench\App\\' : 'App\\'),
102+
'class UserFactory extends Factory',
103+
], join_paths($workingPath, 'workbench', 'database', 'factories', 'UserFactory.php'));
104+
105+
$this->assertFileContains([
106+
sprintf('namespace %sSeeders;', $prefix ? 'Workbench\Database\\' : 'Database\\'),
107+
sprintf('use %sFactories\UserFactory;', $prefix ? 'Workbench\Database\\' : 'Database\\'),
108+
'class DatabaseSeeder extends Seeder',
109+
'// UserFactory::new()->times(10)->create();',
110+
'UserFactory::new()->create([',
111+
], join_paths($workingPath, 'workbench', 'database', 'seeders', 'DatabaseSeeder.php'));
112+
}
113+
114+
/**
115+
* Assert `workbench:install` command executed with `--no-devtool`.
116+
*/
117+
protected function assertCommandExecutedWithoutDevTool(bool $prefix = true): void
118+
{
119+
$workingPath = static::stubWorkingPath();
120+
121+
$this->assertDirectoryDoesNotExist(join_paths($workingPath, 'workbench', 'app'));
122+
$this->assertDirectoryDoesNotExist(join_paths($workingPath, 'workbench', 'database'));
123+
}
124+
125+
/**
126+
* Assert command executed with `workbench:install` or `workbench:devtool --install`.
127+
*/
128+
protected function assertCommandExecutedWithInstall(bool $prefix = true): void
129+
{
130+
$workingPath = static::stubWorkingPath();
131+
132+
$this->assertFileExists(join_paths($workingPath, 'testbench.yaml'));
133+
134+
$config = Config::loadFromYaml($workingPath);
135+
136+
$this->assertSame(default_skeleton_path(), $config['laravel']);
137+
$this->assertSame([
138+
$prefix ? WorkbenchDatabaseSeeder::class : DatabaseSeeder::class,
139+
], $config->seeders);
140+
$this->assertSame([
141+
'asset-publish',
142+
'create-sqlite-db',
143+
'db-wipe',
144+
'migrate-fresh',
145+
], $config->getWorkbenchAttributes()['build']);
146+
$this->assertSame([
147+
'laravel-assets',
148+
], $config->getWorkbenchAttributes()['assets']);
149+
}
150+
151+
/**
152+
* Assert `workbench:install --basic` or `workbench:devtool --basic --install` command executed.
153+
*/
154+
protected function assertCommandFailedWithBasicInstall(bool $prefix = true): void
155+
{
156+
$this->expectException(RuntimeException::class);
157+
$this->expectExceptionMessage('Nova Devtool does not support installation with --basic` option');
158+
}
159+
160+
/**
161+
* Assert `workbench:devtool` command executed with `--no-install`
162+
*/
163+
protected function assertCommandExecutedWithoutInstall(bool $prefix = true): void
164+
{
165+
$workingPath = static::stubWorkingPath();
166+
$environmentFiles = collect(['.env', '.env.example', '.env.dist']);
167+
168+
$this->assertFileDoesNotExist(join_paths($workingPath, 'testbench.yaml'));
169+
170+
$environmentFiles->each(function ($env) use ($workingPath) {
171+
$this->assertFileDoesNotExist(join_paths($workingPath, 'workbench', $env));
172+
});
173+
}
174+
175+
/**
176+
* Assert from `environmentFileDataProviders`
177+
*/
178+
protected function assertFromEnvironmentFileDataProviders(?string $answer, bool $createEnvironmentFile): void
179+
{
180+
$workingPath = static::stubWorkingPath();
181+
182+
if (\is_null($answer) || $createEnvironmentFile === false) {
183+
collect(['.env', '.env.example', '.env.dist'])
184+
->each(function ($file) use ($workingPath) {
185+
$this->assertFalse(is_file(join_paths($workingPath, 'workbench', $file)));
186+
});
187+
} else {
188+
$this->assertTrue(is_file(join_paths($workingPath, 'workbench', $answer)));
189+
}
190+
}
191+
192+
/**
193+
* Assert file does contains data.
194+
*
195+
* @param array<int, string> $contains
196+
*/
197+
protected function assertFileContains(array $contains, string $file, string $message = ''): void
198+
{
199+
$this->assertFileExists($file);
200+
201+
$haystack = file_get_contents($file);
202+
203+
foreach ($contains as $needle) {
204+
$this->assertStringContainsString($needle, $haystack, $message);
205+
}
206+
}
207+
208+
/**
209+
* `environmentFileDataProviders` data provider.
210+
*/
211+
public static function environmentFileDataProviders()
212+
{
213+
yield ['Skip exporting .env', false];
214+
yield ['.env', true];
215+
yield ['.env.example', true];
216+
yield ['.env.dist', true];
217+
}
218+
219+
/**
220+
* Get the stub working path.
221+
*/
222+
protected static function stubWorkingPath(): string
223+
{
224+
return join_paths(__DIR__, sprintf('%s_stubs', class_basename(static::class)));
225+
}
226+
}

0 commit comments

Comments
 (0)