/var/www/vhosts/ihelp.ro/httpdocs/vendor/cakephp/bake/src/Command
NameSizeModeActions
AllCommand.php38990644editdlrm
BakeCommand.php77070644editdlrm
BehaviorCommand.php12380644editdlrm
CellCommand.php34180644editdlrm
CommandCommand.php12310644editdlrm
CommandHelperCommand.php12520644editdlrm
ComponentCommand.php12540644editdlrm
ControllerAllCommand.php27860644editdlrm
ControllerCommand.php94330644editdlrm
EntryCommand.php74160644editdlrm
FixtureAllCommand.php32580644editdlrm
FixtureCommand.php178000644editdlrm
FormCommand.php12070644editdlrm
HelperCommand.php12240644editdlrm
MailerCommand.php16910644editdlrm
MiddlewareCommand.php12490644editdlrm
ModelAllCommand.php27420644editdlrm
ModelCommand.php487300644editdlrm
PluginCommand.php147230644editdlrm
ShellHelperCommand.php12420644editdlrm
SimpleBakeCommand.php47930644editdlrm
TemplateAllCommand.php28420644editdlrm
TemplateCommand.php142920644editdlrm
TestCommand.php267160644editdlrm
Edit: /var/www/vhosts/ihelp.ro/httpdocs/vendor/cakephp/bake/src/Command/TestCommand.php (26716B)
'Model\Entity', 'Table' => 'Model\Table', 'Controller' => 'Controller', 'Component' => 'Controller\Component', 'Behavior' => 'Model\Behavior', 'Helper' => 'View\Helper', 'Shell' => 'Shell', 'Task' => 'Shell\Task', 'ShellHelper' => 'Shell\Helper', 'Cell' => 'View\Cell', 'Form' => 'Form', 'Mailer' => 'Mailer', 'Command' => 'Command', 'CommandHelper' => 'Command\Helper', 'Middleware' => 'Middleware', ]; /** * class types that methods can be generated for * * @var string[] */ public $classSuffixes = [ 'Entity' => '', 'Table' => 'Table', 'Controller' => 'Controller', 'Component' => 'Component', 'Behavior' => 'Behavior', 'Helper' => 'Helper', 'Shell' => 'Shell', 'Task' => 'Task', 'ShellHelper' => 'Helper', 'Cell' => 'Cell', 'Form' => 'Form', 'Mailer' => 'Mailer', 'Command' => 'Command', 'CommandHelper' => 'Helper', 'Middleware' => 'Middleware', ]; /** * Blacklisted methods for controller test cases. * * @var string[] */ protected $blacklistedMethods = [ 'initialize', ]; /** * Internal list of fixtures that have been added so far. * * @var string[] */ protected $_fixtures = []; /** * Execute test generation * * @param \Cake\Console\Arguments $args The command arguments. * @param \Cake\Console\ConsoleIo $io The console io * @return int|null The exit code or null for success */ public function execute(Arguments $args, ConsoleIo $io): ?int { $this->extractCommonProperties($args); if (!$args->hasArgument('type') && !$args->hasArgument('name')) { $this->outputTypeChoices($io); return null; } $type = $this->normalize($args->getArgument('type')); if ($args->getOption('all')) { $this->_bakeAll($type, $args, $io); return null; } if (!$args->hasArgument('name')) { $this->outputClassChoices($type, $io); return null; } $name = $args->getArgument('name'); $name = $this->_getName($name); if ($this->bake($type, $name, $args, $io)) { $io->out('Done'); } return static::CODE_SUCCESS; } /** * Output a list of class types you can bake a test for. * * @param \Cake\Console\ConsoleIo $io The console io * @return void */ protected function outputTypeChoices(ConsoleIo $io): void { $io->out( 'You must provide a class type to bake a test for. The valid types are:', 2 ); $i = 0; foreach ($this->classTypes as $option => $package) { $io->out(++$i . '. ' . $option); } $io->out(''); $io->out('Re-run your command as `cake bake `'); } /** * Output a list of possible classnames you might want to generate a test for. * * @param string $typeName The typename to get classes for. * @param \Cake\Console\ConsoleIo $io The console io * @return void */ protected function outputClassChoices(string $typeName, ConsoleIo $io): void { $type = $this->mapType($typeName); $io->out( 'You must provide a class to bake a test for. Some possible options are:', 2 ); $options = $this->_getClassOptions($type); $i = 0; foreach ($options as $option) { $io->out(++$i . '. ' . $option); } $io->out(''); $io->out('Re-run your command as `cake bake ' . $typeName . ' `'); } /** * Bake all tests for one class type. * * @param string $type The typename to get bake all classes for. * @param \Cake\Console\Arguments $args Arguments * @param \Cake\Console\ConsoleIo $io ConsoleIo instance * @return void */ protected function _bakeAll(string $type, Arguments $args, ConsoleIo $io): void { $mappedType = $this->mapType($type); $classes = $this->_getClassOptions($mappedType); foreach ($classes as $class) { if ($this->bake($type, $class, $args, $io)) { $io->out('Done - ' . $class . ''); } else { $io->out('Failed - ' . $class . ''); } } $io->out('Bake finished'); } /** * Get the possible classes for a given type. * * @param string $namespace The namespace fragment to look for classes in. * @return string[] */ protected function _getClassOptions(string $namespace): array { $classes = []; $base = APP; if ($this->plugin) { $base = Plugin::classPath($this->plugin); } $path = $base . str_replace('\\', DS, $namespace); $files = (new Filesystem())->find($path); foreach ($files as $fileObj) { if ($fileObj->isFile()) { $classes[] = substr($fileObj->getFileName(), 0, -4) ?: ''; } } sort($classes); return $classes; } /** * Completes final steps for generating data to create test case. * * @param string $type Type of object to bake test case for ie. Model, Controller * @param string $className the 'cake name' for the class ie. Posts for the PostsController * @param \Cake\Console\Arguments $args Arguments * @param \Cake\Console\ConsoleIo $io ConsoleIo instance * @return string|bool */ public function bake(string $type, string $className, Arguments $args, ConsoleIo $io) { $type = $this->normalize($type); if (!isset($this->classSuffixes[$type]) || !isset($this->classTypes[$type])) { return false; } $prefix = $this->getPrefix($args); $fullClassName = $this->getRealClassName($type, $className, $prefix); if (!$args->getOption('no-fixture')) { if ($args->getOption('fixtures')) { $fixtures = array_map('trim', explode(',', $args->getOption('fixtures'))); $this->_fixtures = array_filter($fixtures); } elseif ($this->typeCanDetectFixtures($type) && class_exists($fullClassName)) { $io->out('Bake is detecting possible fixtures...'); $testSubject = $this->buildTestSubject($type, $fullClassName); $this->generateFixtureList($testSubject); } } $methods = []; if (class_exists($fullClassName)) { $methods = $this->getTestableMethods($fullClassName); } $mock = $this->hasMockClass($type); [$preConstruct, $construction, $postConstruct] = $this->generateConstructor($type, $fullClassName); $uses = $this->generateUses($type, $fullClassName); $subject = $className; [$namespace, $className] = namespaceSplit($fullClassName); $baseNamespace = Configure::read('App.namespace'); if ($this->plugin) { $baseNamespace = $this->_pluginNamespace($this->plugin); } $subNamespace = substr($namespace, strlen($baseNamespace) + 1); $properties = $this->generateProperties($type, $subject, $fullClassName); $io->out("\n" . sprintf('Baking test case for %s ...', $fullClassName), 1, Shell::QUIET); $contents = $this->createTemplateRenderer() ->set('fixtures', $this->_fixtures) ->set('plugin', $this->plugin) ->set(compact( 'subject', 'className', 'properties', 'methods', 'type', 'fullClassName', 'mock', 'preConstruct', 'postConstruct', 'construction', 'uses', 'baseNamespace', 'subNamespace', 'namespace' )) ->generate('Bake.tests/test_case'); $filename = $this->testCaseFileName($type, $fullClassName); $emptyFile = dirname($filename) . DS . '.gitkeep'; $this->deleteEmptyFile($emptyFile, $io); if ($io->createFile($filename, $contents, $this->force)) { return $contents; } return false; } /** * Checks whether the chosen type can find its own fixtures. * Currently only model, and controller are supported * * @param string $type The Type of object you are generating tests for eg. controller * @return bool */ public function typeCanDetectFixtures(string $type): bool { return in_array($type, ['Controller', 'Table'], true); } /** * Construct an instance of the class to be tested. * So that fixtures can be detected * * @param string $type The type of object you are generating tests for eg. controller * @param string $class The classname of the class the test is being generated for. * @return object And instance of the class that is going to be tested. */ public function buildTestSubject(string $type, string $class) { if ($type === 'Table') { [, $name] = namespaceSplit($class); $name = str_replace('Table', '', $name); if ($this->plugin) { $name = $this->plugin . '.' . $name; } if ($this->getTableLocator()->exists($name)) { $instance = $this->getTableLocator()->get($name); } else { $instance = $this->getTableLocator()->get($name, [ 'connectionName' => $this->connection, ]); } } elseif ($type === 'Controller') { $instance = new $class(new Request(), new Response()); } else { $instance = new $class(); } return $instance; } /** * Gets the real class name from the cake short form. If the class name is already * suffixed with the type, the type will not be duplicated. * * @param string $type The Type of object you are generating tests for eg. controller. * @param string $class the Classname of the class the test is being generated for. * @param string|null $prefix The namespace prefix if any * @return string Real class name */ public function getRealClassName(string $type, string $class, ?string $prefix = null): string { $namespace = Configure::read('App.namespace'); if ($this->plugin) { $namespace = str_replace('/', '\\', $this->plugin); } $suffix = $this->classSuffixes[$type]; $subSpace = $this->mapType($type); if ($suffix && strpos($class, $suffix) === false) { $class .= $suffix; } if (in_array($type, ['Controller', 'Cell'], true) && $prefix) { $subSpace .= '\\' . str_replace('/', '\\', $prefix); } return $namespace . '\\' . $subSpace . '\\' . $class; } /** * Gets the subspace path for a test. * * @param string $type The Type of object you are generating tests for eg. controller. * @return string Path of the subspace. */ public function getSubspacePath(string $type): string { $subspace = $this->mapType($type); return str_replace('\\', DS, $subspace); } /** * Map the types that TestTask uses to concrete types that App::className can use. * * @param string $type The type of thing having a test generated. * @return string * @throws \Cake\Core\Exception\CakeException When invalid object types are requested. */ public function mapType(string $type): string { if (empty($this->classTypes[$type])) { throw new CakeException('Invalid object type: ' . $type); } return $this->classTypes[$type]; } /** * Get methods declared in the class given. * No parent methods will be returned * * @param string $className Name of class to look at. * @return string[] Array of method names. * @throws \ReflectionException */ public function getTestableMethods(string $className): array { $class = new ReflectionClass($className); $out = []; foreach ($class->getMethods() as $method) { if ($method->getDeclaringClass()->getName() !== $className) { continue; } if (!$method->isPublic() || in_array($method->getName(), $this->blacklistedMethods, true)) { continue; } $out[] = $method->getName(); } return $out; } /** * Generate the list of fixtures that will be required to run this test based on * loaded models. * * @param \Cake\ORM\Table|\Cake\Controller\Controller $subject The object you want to generate fixtures for. * @return string[] Array of fixtures to be included in the test. */ public function generateFixtureList($subject): array { $this->_fixtures = []; if ($subject instanceof Table) { $this->_processModel($subject); } elseif ($subject instanceof Controller) { $this->_processController($subject); } /** @psalm-suppress RedundantFunctionCall */ return array_values($this->_fixtures); } /** * Process a model, pull out model name + associations converted to fixture names. * * @param \Cake\ORM\Table $subject A Model class to scan for associations and pull fixtures off of. * @return void */ protected function _processModel(Table $subject): void { $this->_addFixture($subject->getAlias()); foreach ($subject->associations()->keys() as $alias) { $assoc = $subject->getAssociation($alias); $target = $assoc->getTarget(); $name = $target->getAlias(); $subjectClass = get_class($subject); if ($subjectClass !== Table::class && $subjectClass === get_class($target)) { continue; } if (!isset($this->_fixtures[$name])) { $this->_addFixture($target->getAlias()); } } } /** * Process all the models attached to a controller * and generate a fixture list. * * @param \Cake\Controller\Controller $subject A controller to pull model names off of. * @return void */ protected function _processController(Controller $subject): void { try { $model = $subject->loadModel(); } catch (UnexpectedValueException $exception) { // No fixtures needed or possible return; } $models = [$model->getAlias()]; foreach ($models as $model) { [, $model] = pluginSplit($model); $this->_processModel($subject->{$model}); } } /** * Add class name to the fixture list. * Sets the app. or plugin.plugin_name. prefix. * * @param string $name Name of the Model class that a fixture might be required for. * @return void */ protected function _addFixture(string $name): void { if ($this->plugin) { $prefix = 'plugin.' . $this->plugin . '.'; } else { $prefix = 'app.'; } $fixture = $prefix . $this->_fixtureName($name); $this->_fixtures[$name] = $fixture; } /** * Is a mock class required for this type of test? * Controllers require a mock class. * * @param string $type The type of object tests are being generated for eg. controller. * @return bool */ public function hasMockClass(string $type): bool { return $type === 'Controller'; } /** * Generate a constructor code snippet for the type and class name * * @param string $type The Type of object you are generating tests for eg. controller * @param string $fullClassName The full classname of the class the test is being generated for. * @return string[] Constructor snippets for the thing you are building. */ public function generateConstructor(string $type, string $fullClassName): array { [, $className] = namespaceSplit($fullClassName); $pre = $construct = $post = ''; if ($type === 'Table') { $tableName = str_replace('Table', '', $className); $pre = "\$config = \$this->getTableLocator()->exists('{$tableName}') " . "? [] : ['className' => {$className}::class];"; $construct = "\$this->getTableLocator()->get('{$tableName}', \$config);"; } if ($type === 'Behavior') { $pre = '$table = new Table();'; $construct = "new {$className}(\$table);"; } if ($type === 'Entity' || $type === 'Form') { $construct = "new {$className}();"; } if ($type === 'Helper') { $pre = '$view = new View();'; $construct = "new {$className}(\$view);"; } if ($type === 'Command') { $construct = '$this->useCommandRunner();'; } if ($type === 'Component') { $pre = '$registry = new ComponentRegistry();'; $construct = "new {$className}(\$registry);"; } if ($type === 'Shell') { $pre = "\$this->io = \$this->getMockBuilder('Cake\Console\ConsoleIo')->getMock();"; $construct = "new {$className}(\$this->io);"; } if ($type === 'Task') { $pre = "\$this->io = \$this->getMockBuilder('Cake\Console\ConsoleIo')->getMock();"; $construct = "new {$className}(\$this->io);"; } if ($type === 'Cell') { $pre = "\$this->request = \$this->getMockBuilder('Cake\Http\ServerRequest')->getMock();\n"; $pre .= " \$this->response = \$this->getMockBuilder('Cake\Http\Response')->getMock();"; $construct = "new {$className}(\$this->request, \$this->response);"; } if ($type === 'ShellHelper' || $type === 'CommandHelper') { $pre = "\$this->stub = new ConsoleOutput();\n"; $pre .= ' $this->io = new ConsoleIo($this->stub);'; $construct = "new {$className}(\$this->io);"; } return [$pre, $construct, $post]; } /** * Generate property info for the type and class name * * The generated property info consists of a set of arrays that hold the following keys: * * - `description` (the property description) * - `type` (the property docblock type) * - `name` (the property name) * - `value` (optional - the properties initial value) * * @param string $type The Type of object you are generating tests for eg. controller * @param string $subject The name of the test subject. * @param string $fullClassName The Classname of the class the test is being generated for. * @return array An array containing property info */ public function generateProperties(string $type, string $subject, string $fullClassName): array { $properties = []; switch ($type) { case 'Cell': $properties[] = [ 'description' => 'Request mock', 'type' => '\Cake\Http\ServerRequest|\PHPUnit\Framework\MockObject\MockObject', 'name' => 'request', ]; $properties[] = [ 'description' => 'Response mock', 'type' => '\Cake\Http\Response|\PHPUnit\Framework\MockObject\MockObject', 'name' => 'response', ]; break; case 'Shell': case 'Task': $properties[] = [ 'description' => 'ConsoleIo mock', 'type' => '\Cake\Console\ConsoleIo|\PHPUnit\Framework\MockObject\MockObject', 'name' => 'io', ]; break; case 'CommandHelper': case 'ShellHelper': $properties[] = [ 'description' => 'ConsoleOutput stub', 'type' => '\Cake\TestSuite\Stub\ConsoleOutput', 'name' => 'stub', ]; $properties[] = [ 'description' => 'ConsoleIo mock', 'type' => '\Cake\Console\ConsoleIo', 'name' => 'io', ]; break; } if (!in_array($type, ['Controller', 'Command'])) { $properties[] = [ 'description' => 'Test subject', 'type' => '\\' . $fullClassName, 'name' => $subject, ]; } return $properties; } /** * Generate the uses() calls for a type & class name * * @param string $type The Type of object you are generating tests for eg. controller * @param string $fullClassName The Classname of the class the test is being generated for. * @return string[] An array containing used classes */ public function generateUses(string $type, string $fullClassName): array { $uses = []; if ($type === 'Component') { $uses[] = 'Cake\Controller\ComponentRegistry'; } if ($type === 'Helper') { $uses[] = 'Cake\View\View'; } if ($type === 'ShellHelper' || $type === 'CommandHelper') { $uses[] = 'Cake\TestSuite\Stub\ConsoleOutput'; $uses[] = 'Cake\Console\ConsoleIo'; } if ($type === 'Behavior') { $uses[] = 'Cake\ORM\Table'; } $uses[] = $fullClassName; return $uses; } /** * Get the base path to the plugin/app tests. * * @return string */ public function getBasePath(): string { $dir = 'TestCase/'; $path = defined('TESTS') ? TESTS . $dir : ROOT . DS . 'tests' . DS . $dir; if ($this->plugin) { $path = $this->_pluginPath($this->plugin) . 'tests/' . $dir; } return $path; } /** * Make the filename for the test case. resolve the suffixes for controllers * and get the plugin path if needed. * * @param string $type The Type of object you are generating tests for eg. controller * @param string $className The fully qualified classname of the class the test is being generated for. * @return string filename the test should be created on. */ public function testCaseFileName(string $type, string $className): string { $path = $this->getBasePath(); $namespace = Configure::read('App.namespace'); if ($this->plugin) { $namespace = $this->plugin; } $classTail = substr($className, strlen($namespace) + 1); $path = $path . $classTail . 'Test.php'; return str_replace(['/', '\\'], DS, $path); } /** * Build the option parser * * @param \Cake\Console\ConsoleOptionParser $parser Option parser to update * @return \Cake\Console\ConsoleOptionParser */ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser = $this->_setCommonOptions($parser); $types = array_keys($this->classTypes); $types = array_merge($types, array_map([$this, 'underscore'], $types)); $parser->setDescription( 'Bake test case skeletons for classes.' )->addArgument('type', [ 'help' => 'Type of class to bake, can be any of the following:' . ' controller, model, helper, component or behavior.', 'choices' => $types, ])->addArgument('name', [ 'help' => 'An existing class to bake tests for.', ])->addOption('fixtures', [ 'help' => 'A comma separated list of fixture names you want to include.', ])->addOption('no-fixture', [ 'boolean' => true, 'default' => false, 'help' => 'Select if you want to bake without fixture.', ])->addOption('prefix', [ 'default' => false, 'help' => 'Use when baking tests for prefixed controllers.', ])->addOption('all', [ 'boolean' => true, 'help' => 'Bake all classes of the given type', ]); return $parser; } /** * Normalizes string into CamelCase format. * * @param string $string String to inflect * @return string */ protected function normalize(string $string): string { return Inflector::camelize(Inflector::underscore($string)); } /** * Helper to allow under_score format for CLI env usage. * * @param string $string String to inflect * @return string */ protected function underscore(string $string): string { return Inflector::underscore($string); } }