Skip to content

Commit

Permalink
Test class Generator (#8333)
Browse files Browse the repository at this point in the history
* fixing stuff and replacing files lost in rebase

* Fixing namespace test
  • Loading branch information
lonnieezell authored Dec 27, 2023
1 parent e0eea00 commit f4d2ede
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 452 deletions.
425 changes: 0 additions & 425 deletions phpstan-baseline.php

Large diffs are not rendered by default.

67 changes: 40 additions & 27 deletions system/CLI/GeneratorTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ trait GeneratorTrait
*/
protected $classNameLang = '';

/**
* Namespace to use for class.
* Leave null to use the default namespace.
*/
protected ?string $namespace = null;

/**
* Whether to require class name.
*
Expand Down Expand Up @@ -108,7 +114,7 @@ protected function execute(array $params): void
/**
* Generates a class file from an existing template.
*/
protected function generateClass(array $params)
protected function generateClass(array $params): void
{
$this->params = $params;

Expand All @@ -119,7 +125,7 @@ protected function generateClass(array $params)
$target = $this->buildPath($class);

// Check if path is empty.
if (empty($target)) {
if ($target === '') {
return;
}

Expand All @@ -131,14 +137,14 @@ protected function generateClass(array $params)
*
* @param string $view namespaced view name that is generated
*/
protected function generateView(string $view, array $params)
protected function generateView(string $view, array $params): void
{
$this->params = $params;

$target = $this->buildPath($view);

// Check if path is empty.
if (empty($target)) {
if ($target === '') {
return;
}

Expand Down Expand Up @@ -263,8 +269,10 @@ protected function qualifyClassName(): string

if ($class === null && $this->hasClassName) {
// @codeCoverageIgnoreStart
$nameLang = $this->classNameLang ?: 'CLI.generator.className.default';
$class = CLI::prompt(lang($nameLang), null, 'required');
$nameLang = $this->classNameLang !== ''
? $this->classNameLang
: 'CLI.generator.className.default';
$class = CLI::prompt(lang($nameLang), null, 'required');
CLI::newLine();
// @codeCoverageIgnoreEnd
}
Expand Down Expand Up @@ -302,20 +310,15 @@ protected function qualifyClassName(): string
);

// Gets the namespace from input. Don't forget the ending backslash!
$namespace = trim(
str_replace(
'/',
'\\',
$this->getOption('namespace') ?? APP_NAMESPACE
),
'\\'
) . '\\';
$namespace = $this->getNamespace() . '\\';

if (strncmp($class, $namespace, strlen($namespace)) === 0) {
return $class; // @codeCoverageIgnore
}

return $namespace . $this->directory . '\\' . str_replace('/', '\\', $class);
$directoryString = ($this->directory !== null) ? $this->directory . '\\' : '';

return $namespace . $directoryString . str_replace('/', '\\', $class);
}

/**
Expand Down Expand Up @@ -403,14 +406,7 @@ protected function buildContent(string $class): string
*/
protected function buildPath(string $class): string
{
$namespace = trim(
str_replace(
'/',
'\\',
$this->getOption('namespace') ?? APP_NAMESPACE
),
'\\'
);
$namespace = $this->getNamespace();

// Check if the namespace is actually defined and we are not just typing gibberish.
$base = Services::autoloader()->getNamespace($namespace);
Expand All @@ -426,7 +422,9 @@ protected function buildPath(string $class): string
return '';
}

$base = realpath($base) ?: $base;
$realpath = realpath($base);
$base = ($realpath !== false) ? $realpath : $base;

$file = $base . DIRECTORY_SEPARATOR
. str_replace(
'\\',
Expand All @@ -444,6 +442,23 @@ protected function buildPath(string $class): string
) . DIRECTORY_SEPARATOR . $this->basename($file);
}

/**
* Gets the namespace from the command-line option,
* or the default namespace if the option is not set.
* Can be overridden by directly setting $this->namespace.
*/
protected function getNamespace(): string
{
return $this->namespace ?? trim(
str_replace(
'/',
'\\',
$this->getOption('namespace') ?? APP_NAMESPACE
),
'\\'
);
}

/**
* Allows child generators to modify the internal `$hasClassName` flag.
*
Expand Down Expand Up @@ -483,10 +498,8 @@ protected function setEnabledSuffixing(bool $enabledSuffixing)
/**
* Gets a single command-line option. Returns TRUE if the option exists,
* but doesn't have a value, and is simply acting as a flag.
*
* @return mixed
*/
protected function getOption(string $name)
protected function getOption(string $name): string|bool|null
{
if (! array_key_exists($name, $this->params)) {
return CLI::getOption($name);
Expand Down
85 changes: 85 additions & 0 deletions system/Commands/Generators/TestGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace CodeIgniter\Commands\Generators;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\GeneratorTrait;

/**
* Generates a skeleton command file.
*/
class TestGenerator extends BaseCommand
{
use GeneratorTrait;

/**
* The Command's Group
*
* @var string
*/
protected $group = 'Generators';

/**
* The Command's Name
*
* @var string
*/
protected $name = 'make:test';

/**
* The Command's Description
*
* @var string
*/
protected $description = 'Generates a new test file.';

/**
* The Command's Usage
*
* @var string
*/
protected $usage = 'make:test <name> [options]';

/**
* The Command's Arguments
*
* @var array<string, string>
*/
protected $arguments = [
'name' => 'The command class name.',
];

/**
* The Command's Options
*
* @var array<string, string>
*/
protected $options = [
'--namespace' => 'Set root namespace. Default: "APP_NAMESPACE".',
'--force' => 'Force overwrite existing file.',
];

/**
* Actually execute a command.
*/
public function run(array $params)
{
$this->component = 'Test';
$this->template = 'test.tpl.php';
$this->namespace = 'Tests';

$this->classNameLang = 'CLI.generator.className.test';
$this->generateClass($params);
}
}
18 changes: 18 additions & 0 deletions system/Commands/Generators/Views/test.tpl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<@php

namespace {namespace};

use CodeIgniter\Test\CIUnitTestCase;

class {class} extends CIUnitTestCase
{
protected function setUp(): void
{
parent::setUp();
}

public function testExample(): void
{
//
}
}
1 change: 1 addition & 0 deletions system/Config/AutoloadConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class AutoloadConfig
protected $corePsr4 = [
'CodeIgniter' => SYSTEMPATH,
'Config' => APPPATH . 'Config',
'Tests' => ROOTPATH . 'tests',
];

/**
Expand Down
1 change: 1 addition & 0 deletions system/Language/en/CLI.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
'migration' => 'Migration class name',
'model' => 'Model class name',
'seeder' => 'Seeder class name',
'test' => 'Test class name',
'validation' => 'Validation class name',
],
'commandType' => 'Command type',
Expand Down
46 changes: 46 additions & 0 deletions tests/system/Commands/TestGeneratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace CodeIgniter\Commands;

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\StreamFilterTrait;

/**
* @internal
*
* @group Others
*/
final class TestGeneratorTest extends CIUnitTestCase
{
use StreamFilterTrait;

protected function tearDown(): void
{
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
$file = str_replace('ROOTPATH' . DIRECTORY_SEPARATOR, ROOTPATH, trim(substr($result, 14)));
$dir = dirname($file);
if (is_file($file)) {
unlink($file);
}
if (is_dir($dir)) {
rmdir($dir);
}
}

public function testGenerateTest(): void
{
command('make:test Foo/Bar');
$this->assertFileExists(ROOTPATH . 'tests/Foo/Bar.php');
}
}
1 change: 1 addition & 0 deletions tests/system/Commands/Utilities/NamespacesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function testNamespacesCommandCodeIgniterOnly(): void
+---------------+-------------------------+--------+
| CodeIgniter | ROOTPATH/system | Yes |
| Config | APPPATH/Config | Yes |
| Tests | ROOTPATH/tests | Yes |
| App | ROOTPATH/app | Yes |
| Tests\Support | ROOTPATH/tests/_support | Yes |
+---------------+-------------------------+--------+
Expand Down

0 comments on commit f4d2ede

Please sign in to comment.