From 1b7c2cd3366e8961176762d9a59a57676e79fb0e Mon Sep 17 00:00:00 2001 From: Ibrahim Date: Wed, 16 Oct 2024 15:47:14 +0300 Subject: [PATCH] refactor: Introduced new Way to Test CLI Commands --- phpunit.xml | 2 + .../test/cli/CreateAPITestCaseTest.php | 234 +++++++----------- .../test/session/SessionsManagerTest.php | 4 +- webfiori/framework/cli/CLITestCase.php | 75 ++++++ 4 files changed, 167 insertions(+), 148 deletions(-) create mode 100644 webfiori/framework/cli/CLITestCase.php diff --git a/phpunit.xml b/phpunit.xml index 4059d62c..cf553cde 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -45,6 +45,8 @@ ./webfiori/framework/cli/commands/UpdateTableCommand.php ./webfiori/framework/cli/commands/VersionCommand.php ./webfiori/framework/cli/commands/WHelpCommand.php + ./webfiori/framework/cli/CLITestCase.php + ./webfiori/framework/cli/CLIUtils.php ./webfiori/framework/cli/helpers/ClassInfoReader.php ./webfiori/framework/cli/helpers/CreateBackgroundTask.php diff --git a/tests/webfiori/framework/test/cli/CreateAPITestCaseTest.php b/tests/webfiori/framework/test/cli/CreateAPITestCaseTest.php index e4a3a11c..5413a95a 100644 --- a/tests/webfiori/framework/test/cli/CreateAPITestCaseTest.php +++ b/tests/webfiori/framework/test/cli/CreateAPITestCaseTest.php @@ -1,55 +1,32 @@ setArgsVector([ - 'webfiori', - 'create', + $this->assertEquals([ + "Error: The argument --manager has invalid value.\n", + ], $this->executeMultiCommand([ + CreateCommand::class, '--c' => 'api-test', '--manager' => 'A', '--service' => 'c' - ]); - $runner->setInputs([ - - ]); - $exitCode = $runner->start(); - $this->assertEquals(-1, $exitCode); - $this->assertEquals([ - "Error: The argument --manager has invalid value.\n", - - ], $runner->getOutput()); -// $this->assertTrue(class_exists('\\app\\commands\\NewCLICommand')); -// $this->removeClass('\\app\\commands\\NewCLICommand'); + ])); + $this->assertEquals(-1, $this->getExitCode()); } /** * @test */ public function testCreateAPITestCase01() { - $runner = App::getRunner(); - $runner->setArgsVector([ - 'webfiori', - 'create', - '--c' => 'api-test', - '--manager' => TasksServicesManager::class, - '--service' => 'c' - ]); - $runner->setInputs([ - "0", - "y" - ]); - $exitCode = $runner->start(); - $this->assertEquals(0, $exitCode); $path = ROOT_PATH.DS."tests".DS."webfiori".DS."framework".DS."scheduler".DS."webServices"; $this->assertEquals([ "Info: Selected services manager has no service with name 'c'.\n", @@ -65,8 +42,18 @@ public function testCreateAPITestCase01() { "Path: ".$path."\n", "Would you like to use default parameters?(Y/n)\n", "Info: New class was created at \"".$path."\".\n" - ], $runner->getOutput()); - $clazz = '\tests\webfiori\\framework\scheduler\webServices\\TasksLoginServiceTest'; + ], $this->executeMultiCommand([ + CreateCommand::class, + '--c' => 'api-test', + '--manager' => TasksServicesManager::class, + '--service' => 'c' + ], [ + "0", + "y" + ])); + + $this->assertEquals(0, $this->getExitCode()); + $clazz = '\\tests\webfiori\\framework\scheduler\webServices\\TasksLoginServiceTest'; $this->assertTrue(class_exists($clazz)); $this->removeClass($clazz); } @@ -74,24 +61,18 @@ public function testCreateAPITestCase01() { * @test */ public function testCreateAPITestCase02() { - $runner = App::getRunner(); - $runner->setArgsVector([ - 'webfiori', - 'create', + $path = ROOT_PATH.DS."tests".DS."webfiori".DS."framework".DS."scheduler".DS."webServices"; + $this->assertEquals([ + "Info: New class was created at \"".$path."\".\n" + ], $this->executeMultiCommand([ + CreateCommand::class, '--c' => 'api-test', '--manager' => TasksServicesManager::class, '--service' => 'get-tasks', '--defaults' - ]); - $runner->setInputs([ - ]); - $exitCode = $runner->start(); - $this->assertEquals(0, $exitCode); - $path = ROOT_PATH.DS."tests".DS."webfiori".DS."framework".DS."scheduler".DS."webServices"; - $this->assertEquals([ - "Info: New class was created at \"".$path."\".\n" - ], $runner->getOutput()); - $clazz = '\tests\webfiori\\framework\scheduler\webServices\\GetTasksServiceTest'; + ])); + $this->assertEquals(0, $this->getExitCode()); + $clazz = '\\tests\webfiori\\framework\scheduler\webServices\\GetTasksServiceTest'; $this->assertTrue(class_exists($clazz)); $this->removeClass($clazz); } @@ -99,23 +80,6 @@ public function testCreateAPITestCase02() { * @test */ public function testCreateAPITestCase03() { - $runner = App::getRunner(); - $runner->setArgsVector([ - 'webfiori', - 'create', - '--c' => 'api-test', - '--service' => 'get-tasks', - ]); - $runner->setInputs([ - '\webfiori\\framework\scheduler\webServices\\TasksServicesManager', - 'n', - '10', - '', - '', - - ]); - $exitCode = $runner->start(); - $this->assertEquals(0, $exitCode); $path = ROOT_PATH.DS."tests".DS."webfiori".DS."framework".DS."scheduler".DS."webServices"; $this->assertEquals([ "Please enter services manager information:\n", @@ -128,8 +92,20 @@ public function testCreateAPITestCase03() { "Enter a name for the new class:\n", "Enter an optional namespace for the class: Enter = 'tests\webfiori\\framework\scheduler\webServices'\n", "Info: New class was created at \"".$path."\".\n" - ], $runner->getOutput()); - $clazz = '\tests\webfiori\\framework\scheduler\webServices\\GetTasksServiceTest'; + ], $this->executeMultiCommand([ + CreateCommand::class, + '--c' => 'api-test', + '--service' => 'get-tasks', + ], [ + '\webfiori\\framework\scheduler\webServices\\TasksServicesManager', + 'n', + '10', + '', + '', + ])); + $this->assertEquals(0, $this->getExitCode()); + + $clazz = '\\tests\webfiori\\framework\scheduler\webServices\\GetTasksServiceTest'; $this->assertTrue(class_exists($clazz)); $this->removeClass($clazz); } @@ -137,25 +113,6 @@ public function testCreateAPITestCase03() { * @test */ public function testCreateAPITestCase04() { - $runner = App::getRunner(); - - - $runner->setArgsVector([ - 'webfiori', - 'create', - '--c' => 'api-test', - '--service' => 'say-hi-service', - ]); - $runner->setInputs([ - '\\tests\\apis\\multiple\\ServicesManager00', - 'n', - '10', - '', - '', - - ]); - $exitCode = $runner->start(); - $this->assertEquals(0, $exitCode); $path = ROOT_PATH.DS."tests".DS."tests".DS."apis".DS."multiple"; $this->assertEquals([ "Please enter services manager information:\n", @@ -168,7 +125,19 @@ public function testCreateAPITestCase04() { "Enter a name for the new class:\n", "Enter an optional namespace for the class: Enter = 'tests\\tests\apis\multiple'\n", "Info: New class was created at \"".$path."\".\n" - ], $runner->getOutput()); + ], $this->executeMultiCommand([ + CreateCommand::class, + '--c' => 'api-test', + '--service' => 'say-hi-service', + ], [ + '\\tests\\apis\\multiple\\ServicesManager00', + 'n', + '10', + '', + '', + ])); + $this->assertEquals(0, $this->getExitCode()); + $clazz = '\\tests\\tests\\apis\\multiple\\WebService00Test'; $this->assertTrue(class_exists($clazz)); $this->removeClass($clazz); @@ -178,46 +147,19 @@ public function testCreateAPITestCase04() { * @test */ public function testCreateAPITestCase05() { - $runner = App::getRunner(); - $runner->setArgsVector([ - 'webfiori', - 'create', - '--c' => 'api-test', - '--manager' => '\\tests\\apis\\emptyService\\EmptyServicesManager', - ]); - $runner->setInputs(); - - $exitCode = $runner->start(); - $this->assertEquals(-1, $exitCode); - $this->assertEquals([ "Info: Provided services manager has 0 registered services.\n", - ], $runner->getOutput()); + ], $this->executeMultiCommand([ + CreateCommand::class, + '--c' => 'api-test', + '--manager' => '\\tests\\apis\\emptyService\\EmptyServicesManager', + ])); + $this->assertEquals(-1, $this->getExitCode()); } /** * @test */ public function testCreateAPITestCase06() { - $runner = App::getRunner(); - - - $runner->setArgsVector([ - 'webfiori', - 'create', - '--c' => 'api-test', - '--service' => 'say-hi-service', - ]); - $runner->setInputs([ - '\\tests\\apis\\multiple\\WebService00', - '\\tests\\apis\\multiple\\ServicesManager00', - 'n', - '10', - '', - '', - - ]); - $exitCode = $runner->start(); - $this->assertEquals(0, $exitCode); $path = ROOT_PATH.DS."tests".DS."tests".DS."apis".DS."multiple"; $this->assertEquals([ "Please enter services manager information:\n", @@ -232,7 +174,19 @@ public function testCreateAPITestCase06() { "Enter a name for the new class:\n", "Enter an optional namespace for the class: Enter = 'tests\\tests\apis\multiple'\n", "Info: New class was created at \"".$path."\".\n" - ], $runner->getOutput()); + ], $this->executeMultiCommand([ + CreateCommand::class, + '--c' => 'api-test', + '--service' => 'say-hi-service', + ], [ + '\\tests\\apis\\multiple\\WebService00', + '\\tests\\apis\\multiple\\ServicesManager00', + 'n', + '10', + '', + '', + ])); + $this->assertEquals(0, $this->getExitCode()); $clazz = '\\tests\\tests\\apis\\multiple\\WebService00Test'; $this->assertTrue(class_exists($clazz)); $this->removeClass($clazz); @@ -241,42 +195,30 @@ public function testCreateAPITestCase06() { * @test */ public function testCreateAPITestCase07() { - $runner = App::getRunner(); - $runner->setArgsVector([ - 'webfiori', - 'create', - '--c' => 'api-test', - '--manager' => '\\tests\\apis\\emptyService\\Xyz', - ]); - $runner->setInputs(); - - $exitCode = $runner->start(); - $this->assertEquals(-1, $exitCode); - $this->assertEquals([ "Error: The argument --manager has invalid value.\n", - ], $runner->getOutput()); + ], $this->executeMultiCommand([ + CreateCommand::class, + '--c' => 'api-test', + '--manager' => '\\tests\\apis\\emptyService\\Xyz', + ])); + $this->assertEquals(-1, $this->getExitCode()); } /** * @test */ public function testCreateAPITestCase08() { - $runner = App::getRunner(); - $runner->setArgsVector([ - 'webfiori', - 'create', + $path = ROOT_PATH.DS."tests".DS."tests".DS."apis".DS."multiple"; + $this->assertEquals([ + "Info: New class was created at \"".$path."\".\n" + ], $this->executeMultiCommand([ + CreateCommand::class, '--c' => 'api-test', '--service' => 'say-hi-service-2', '--manager' => '\\tests\\apis\\multiple\\ServicesManager00', '--defaults' - ]); - $runner->setInputs(); - $exitCode = $runner->start(); - $this->assertEquals(0, $exitCode); - $path = ROOT_PATH.DS."tests".DS."tests".DS."apis".DS."multiple"; - $this->assertEquals([ - "Info: New class was created at \"".$path."\".\n" - ], $runner->getOutput()); + ])); + $this->assertEquals(0, $this->getExitCode()); $clazz = '\\tests\\tests\\apis\\multiple\\WebService01Test'; $this->assertTrue(class_exists($clazz)); $this->removeClass($clazz); diff --git a/tests/webfiori/framework/test/session/SessionsManagerTest.php b/tests/webfiori/framework/test/session/SessionsManagerTest.php index 3ae3e4fa..b7b41706 100644 --- a/tests/webfiori/framework/test/session/SessionsManagerTest.php +++ b/tests/webfiori/framework/test/session/SessionsManagerTest.php @@ -314,8 +314,8 @@ public function testInitSessionsDb() { SessionsManager::reset(); $sto = new DatabaseSessionStorage(); $sto->getController()->createTables()->execute(); - $sto->getController()->table('session_data')->select()->execute(); - $sto->getController()->table('sessions')->select()->execute(); +// $sto->getController()->table('session_data')->select()->execute(); +// $sto->getController()->table('sessions')->select()->execute(); $this->assertTrue(true); } /** diff --git a/webfiori/framework/cli/CLITestCase.php b/webfiori/framework/cli/CLITestCase.php new file mode 100644 index 00000000..fca37ce1 --- /dev/null +++ b/webfiori/framework/cli/CLITestCase.php @@ -0,0 +1,75 @@ +setRunner(App::getRunner()); + } + /** + * Register multiple commands and simulate the process of executing the app + * as if in production environment. + * + * @param array $argv An array that represents arguments vector. The array + * can be indexed or associative. If associative, the key will represent + * an option and the value of the key will represent its value. First + * index should contain the name of the command that will be executed from + * the registered commands. Note that first argument can be the name of + * the class that represent the command obtained using the syntax Class::class. + * + * @param array $userInputs An array that holds user inputs. Each index + * should hold one line that represent an input to specific prompt. + * + * @param array $commands An array that holds objects of type 'CLICommand'. + * Each object represents the registered command. + * + * @param string $default A string that represents the name of the command + * that will get executed by default if no command name is provided + * in arguments victor. + * + * @return array The method will return an array of strings that represents + * the output of execution. + */ + public function executeMultiCommand(array $argv = [], array $userInputs = [], array $commands = [], string $default = ''): array { + if (count($argv) != 0) { + if (class_exists($argv[0])) { + $c = new $argv[0]; + if ($c instanceof CLICommand) { + $argv[0] = $c->getName(); + } + } + } + return parent::executeMultiCommand($argv, $userInputs, $commands, $default); + } + /** + * Removes a class given its file path. + * + * This method is mainly used by the test cases which creates classes. Its + * a cleanup method. + * + * @param string $classPath + */ + public function removeClass(string $classPath) { + $file = new File(ROOT_PATH.DS.trim($classPath,'\\').'.php'); + $file->remove(); + } +}