diff --git a/bin/InitAppCommand.php b/bin/InitAppCommand.php
index 5ed5b00..403d615 100644
--- a/bin/InitAppCommand.php
+++ b/bin/InitAppCommand.php
@@ -31,6 +31,7 @@ public function exec(): int {
}
try {
+ $this->println('Creating new app at "'.$appPath.'" ...');
$this->createAppClass($appPath, $dirName);
$this->createEntryPoint($appPath, $dirName, $entry);
$this->success('App created successfully.');
@@ -44,8 +45,8 @@ public function exec(): int {
}
}
private function createAppClass(string $appPath, string $dirName) {
- $this->println('Creating "'.$dirName.'/app.php"...');
- $file = new File($appPath.DIRECTORY_SEPARATOR.'app.php');
+ $this->println('Creating "'.$dirName.'/main.php"...');
+ $file = new File($appPath.DIRECTORY_SEPARATOR.'main.php');
if (!$file->isExist()) {
$file->append("warning('File app.php already exist!');
+ $this->warning('File main.php already exist!');
}
private function createEntryPoint(string $appPath, string $dir, string $eName) {
$this->println('Creating "'.$dir.'/'.$eName.'"...');
@@ -76,7 +77,7 @@ private function createEntryPoint(string $appPath, string $dir, string $eName) {
if (!$file->isExist()) {
$data = "#!/usr/bin/env php\n"
."create(true);
file_put_contents($file->getDir().DIRECTORY_SEPARATOR.$eName, $data);
diff --git a/bin/app.php b/bin/main.php
similarity index 100%
rename from bin/app.php
rename to bin/main.php
diff --git a/bin/wfc b/bin/wfc
index aec2f9f..571395f 100644
--- a/bin/wfc
+++ b/bin/wfc
@@ -1,3 +1,3 @@
#!/usr/bin/env php
register(new HelloWorldCommand());
-
- //Set arguments vector
- $runner->setArgsVector([
- 'app.php',//First argument is always name of entry point.
- //Can be set to anything since its testing env.
- 'hello'
- ]);
-
- //Set user inputs.
- //Must be called to use Array as input and output stream even if there are no inputs.
- $runner->setInputs();
-
- //Start the process
- $exitStatus = $runner->start();
-
- //Verify test results
- $this->assertEquals(0, $exitStatus);
+ //A basic test case without using arg vector or user inputs
$this->assertEquals([
- "Hello World!\n"
- ], $runner->getOutput());
+ "Hello World!".self::NL
+ ], $this->executeSingleCommand([new HelloWorldCommand()]));
}
/**
* @test
*/
public function test01() {
- $runner = new Runner();
- $runner->register(new HelloWorldCommand());
-
- $runner->setArgsVector([
- 'app.php',
- 'hello',
- '--person-name' => 'Ibrahim BinAlshikh'
- ]);
- $runner->setInputs();
- $exitStatus = $runner->start();
- $this->assertEquals(0, $exitStatus);
- $this->assertEquals([
- "Hello Ibrahim BinAlshikh!\n"
- ], $runner->getOutput());
- }
- /**
- * @test
- */
- public function test03() {
- $runner = new Runner();
- $runner->register(new HelpCommand());
- $runner->register(new HelloWorldCommand());
- $runner->setDefaultCommand('help');
- $runner->setArgsVector([
- 'app.php',
- ]);
- $runner->setInputs();
- $exitStatus = $runner->start();
- $this->assertEquals(0, $exitStatus);
+ //A test case that uses arg vector
$this->assertEquals([
- "Usage:\n",
- " command [arg1 arg2=\"val\" arg3...]\n\n",
- "Global Arguments:\n",
- " --ansi:[Optional] Force the use of ANSI output.\n",
- "Available Commands:\n",
- " help: Display CLI Help. To display help for specific command, use the argument \"--command-name\" with this command.\n",
- " hello: A command to show greetings.\n"
- ], $runner->getOutput());
+ "Hello Ibrahim BinAlshikh!\n".self::NL
+ ], $this->executeSingleCommand(new HelloWorldCommand(), [
+ '--person-name' => 'Ibrahim BinAlshikh'
+ ]));
}
}
diff --git a/phpunit.xml b/phpunit.xml
index 84ab3c8..9be29bd 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -9,6 +9,7 @@
./webfiori/cli/Formatter.php
./webfiori/cli/KeysMap.php
./webfiori/cli/Runner.php
+ ./webfiori/cli/CommandTestCase.php
./webfiori/cli/InputValidator.php
./webfiori/cli/streams/ArrayInputStream.php
./webfiori/cli/streams/ArrayOutputStream.php
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 48b1e17..71b6041 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -41,6 +41,7 @@
require_once $baseDir.DS.'Runner.php';
require_once $baseDir.DS.'Option.php';
require_once $baseDir.DS.'InputValidator.php';
+require_once $baseDir.DS.'CommandTestCase.php';
require_once $baseDir.DS.'streams'.DS.'ArrayInputStream.php';
require_once $baseDir.DS.'streams'.DS.'ArrayOutputStream.php';
require_once $baseDir.DS.'streams'.DS.'FileInputStream.php';
diff --git a/tests/webfiori/tests/cli/CLICommandTest.php b/tests/webfiori/tests/cli/CLICommandTest.php
index 2555014..bb8529d 100644
--- a/tests/webfiori/tests/cli/CLICommandTest.php
+++ b/tests/webfiori/tests/cli/CLICommandTest.php
@@ -11,7 +11,7 @@
use webfiori\tests\cli\TestCommand;
use webfiori\tests\TestStudent;
-class CLICommandTest extends TestCase {
+class CLICommandTestCase extends TestCase {
/**
* @test
*/
diff --git a/tests/webfiori/tests/cli/InitAppCommandTest.php b/tests/webfiori/tests/cli/InitAppCommandTest.php
index 56a27ed..2259d5c 100644
--- a/tests/webfiori/tests/cli/InitAppCommandTest.php
+++ b/tests/webfiori/tests/cli/InitAppCommandTest.php
@@ -20,7 +20,7 @@ public function test00() {
$r->setDefaultCommand('init');
$r->setInputs([]);
$r->setArgsVector([
- 'app.php',
+ 'main.php',
'init'
]);
$this->assertEquals(-1, $r->start());
@@ -37,7 +37,7 @@ public function test01() {
$r->setDefaultCommand('init');
$r->setInputs([]);
$r->setArgsVector([
- 'app.php',
+ 'main.php',
'init',
'--dir' => "test\0a"
]);
@@ -53,13 +53,15 @@ public function test02() {
->setDefaultCommand('init')
->setInputs([])
->setArgsVector([
- 'app.php',
+ 'main.php',
'init',
'--dir' => 'test'
]);
+ $appPath = ROOT_DIR.DS.'test';
$this->assertEquals(0, $r->start());
$this->assertEquals([
- "Creating \"test/app.php\"...\n",
+ "Creating new app at \"$appPath\" ...\n",
+ "Creating \"test/main.php\"...\n",
"Creating \"test/test\"...\n",
"Success: App created successfully.\n"
], $r->getOutput());
@@ -74,19 +76,21 @@ public function test03() {
$r->setDefaultCommand('init');
$r->setInputs([]);
$r->setArgsVector([
- 'app.php',
+ 'main.php',
'init',
'--dir' => 'test'
]);
$this->assertEquals(0, $r->start());
+ $appPath = ROOT_DIR.DS.'test';
$this->assertEquals([
- "Creating \"test/app.php\"...\n",
- "Warning: File app.php already exist!\n",
+ "Creating new app at \"$appPath\" ...\n",
+ "Creating \"test/main.php\"...\n",
+ "Warning: File main.php already exist!\n",
"Creating \"test/test\"...\n",
"Warning: File test already exist!\n",
"Success: App created successfully.\n"
], $r->getOutput());
- unlink(ROOT_DIR.DS.'test'.DS.'app.php');
+ unlink(ROOT_DIR.DS.'test'.DS.'main.php');
unlink(ROOT_DIR.DS.'test'.DS.'test');
rmdir(ROOT_DIR.DS.'test');
}
@@ -99,20 +103,22 @@ public function test04() {
$r->setDefaultCommand('init');
$r->setInputs([]);
$r->setArgsVector([
- 'app.php',
+ 'main.php',
'init',
'--dir' => 'test2',
'--entry' => 'bang'
]);
$this->assertEquals(0, $r->start());
+ $appPath = ROOT_DIR.DS.'test2';
$this->assertEquals([
- "Creating \"test2/app.php\"...\n",
+ "Creating new app at \"$appPath\" ...\n",
+ "Creating \"test2/main.php\"...\n",
"Creating \"test2/bang\"...\n",
"Success: App created successfully.\n"
], $r->getOutput());
- unlink(ROOT_DIR.DS.'test2'.DS.'app.php');
- unlink(ROOT_DIR.DS.'test2'.DS.'bang');
- rmdir(ROOT_DIR.DS.'test2');
+ unlink($appPath.DS.'main.php');
+ unlink($appPath.DS.'bang');
+ rmdir($appPath);
}
}
diff --git a/tests/webfiori/tests/cli/RunnerTest.php b/tests/webfiori/tests/cli/RunnerTest.php
index e67c589..5f10cdd 100644
--- a/tests/webfiori/tests/cli/RunnerTest.php
+++ b/tests/webfiori/tests/cli/RunnerTest.php
@@ -1,23 +1,23 @@
register(new Command00());
- $runner->setInputs([]);
- $this->assertEquals(-1, $runner->runCommand(null, [
- 'super-hero',
- 'name' => 'Ok'
- ]));
- $this->assertEquals(-1, $runner->getLastCommandExitStatus());
$this->assertEquals([
"Error: The following argument(s) have invalid values: 'name'\n",
"Info: Allowed values for the argument 'name':\n",
"Ibrahim\n",
"Ali\n"
- ], $runner->getOutput());
+ ], $this->executeSingleCommand(new Command00(), [
+ 'super-hero',
+ 'name' => 'Ok'
+ ]));
+ $this->assertEquals(-1, $this->getExitCode());
}
/**
* @test
*/
public function testRunner04() {
- $runner = new Runner();
- $runner->register(new Command00());
- $runner->setInputs([]);
- $this->assertEquals(-1, $runner->runCommand(null, [
- 'super-hero',
- 'name' => 'Ok',
- '--ansi'
- ]));
- $this->assertEquals(-1, $runner->getLastCommandExitStatus());
$this->assertEquals([
"\e[1;91mError: \e[0mThe following argument(s) have invalid values: 'name'\n",
"\e[1;34mInfo: \e[0mAllowed values for the argument 'name':\n",
"Ibrahim\n",
"Ali\n"
- ], $runner->getOutput());
+ ], $this->executeSingleCommand(new Command00(), [
+ 'name' => 'Ok',
+ '--ansi'
+ ]));
+ $this->assertEquals(-1, $this->getExitCode());
}
/**
* @test
@@ -166,11 +157,7 @@ public function testRunner05() {
* @test
*/
public function testRunner06() {
- $runner = new Runner();
- $runner->register(new Command00());
- $runner->setDefaultCommand('help');
- $runner->setInputs([]);
- $this->assertEquals(0, $runner->runCommand(new HelpCommand(), []));
+
$this->assertEquals([
"Usage:\n",
" command [arg1 arg2=\"val\" arg3...]\n\n",
@@ -178,7 +165,12 @@ public function testRunner06() {
" --ansi:[Optional] Force the use of ANSI output.\n",
"Available Commands:\n",
" super-hero: A command to display hero's name.\n",
- ], $runner->getOutput());
+ " help: Display CLI Help. To display help for specific command, use the argument \"--command-name\" with this command.\n"
+ ], $this->executeMultiCommand([
+ new Command00(),
+ new HelpCommand()
+ ], 'help'));
+ $this->assertEquals(0, $this->getExitCode());
}
/**
* @test
diff --git a/webfiori/cli/CommandTestCase.php b/webfiori/cli/CommandTestCase.php
new file mode 100644
index 0000000..51f1d21
--- /dev/null
+++ b/webfiori/cli/CommandTestCase.php
@@ -0,0 +1,157 @@
+getRunner(true);
+
+ foreach ($commands as $command) {
+ $runner->register($command);
+ }
+ $runner->setDefaultCommand($default);
+ $this->exec($argv, $userInputs);
+
+ return $this->getOutput();
+ }
+ /**
+ * Executes a specific command and return its output as an array.
+ *
+ * @param CLICommand $command The command that will be tested.
+ *
+ * @param array $argv Arguments vector that will be passed to the command.
+ * This can be an associative array of options and values or just options.
+ *
+ * @param array $userInputs A sequence of strings that represents user inputs
+ * when the command is executing. Each index in the array represents a single
+ * line of input.
+ *
+ * @return array The method will return an array that will hold
+ * outputs line by line in each index.
+ */
+ public function executeSingleCommand(CLICommand $command, array $argv = [], array $userInputs = []) : array {
+ $this->getRunner(true)->register($command);
+ $this->exec($argv, $userInputs, $command);
+
+ return $this->getOutput();
+ }
+ /**
+ * Returns an integer thar represents exit status of running specific command.
+ *
+ * @return int Default return value is 0.
+ */
+ public function getExitCode() : int {
+ if ($this->exitStatus === null) {
+ $this->exitStatus = 0;
+ }
+
+ return $this->exitStatus;
+ }
+ /**
+ * Returns an array that holds all outputs that was generated by running specific
+ * command.
+ *
+ * @return array If no command was executed, the array will be empty. Other
+ * than that, the array will hold outputs line by line in each index.
+ */
+ public function getOutput() : array {
+ if ($this->outputs === null) {
+ $this->outputs = [];
+ }
+
+ return $this->outputs;
+ }
+ /**
+ * Returns the instance that the class is using to execute the commands.
+ *
+ * @param bool $reset If set to true, input stream, output stream and,
+ * registered commands of the runner will reset to default.
+ *
+ * @return Runner The instance that the class is using to execute the commands.
+ */
+ public function getRunner(bool $reset = false) : Runner {
+ if ($this->runner === null) {
+ $this->runner = new Runner();
+ }
+
+ if ($reset) {
+ $this->runner->reset();
+ }
+
+ return $this->runner;
+ }
+
+ private function exec(array $argv, array $userInputs, CLICommand $command = null) {
+ if ($command !== null) {
+ $key = array_search($command->getName(), $argv);
+
+ if ($key != 0 || $key === false) {
+ $argv = array_merge(['main.php', $command->getName()], $argv);
+ } else {
+ $argv = array_merge(['main.php'], $argv);
+ }
+ } else {
+ $argv = array_merge(['main.php'], $argv);
+ }
+ $runner = $this->getRunner();
+
+ //Set arguments vector
+ $runner->setArgsVector($argv);
+
+ //Set user inputs.
+ //Must be called to use Array as input and output stream even if there are no inputs.
+ $runner->setInputs($userInputs);
+
+ //Start the process
+ $this->exitStatus = $runner->start();
+
+ $this->outputs = $runner->getOutput();
+ }
+}