File: D:/HostingSpaces/brameda/brameda.nl/app/Komma/Kms/QualityAssurance/BaseTestController.php
<?php
namespace App\Komma\Kms\QualityAssurance;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Output\ConsoleOutput;
/**
* Class BaseTestController
*
* Used for building test controllers
*
* @package App\Komma|Kms\QualityAssurance
*/
abstract class BaseTestController
{
/**
* Folder where the Unit, Feature, test folders and Reports folder is stored
* @var string $testsFolder
*/
protected $testsFolder;
/**
* Folder where the browser screenshots are stored
*/
protected $screenshotFolder;
/**
* @var string The directory this file resides in relative to the root of this project.
*/
protected $baseDirectory;
/** @var ConsoleOutput */
protected $output;
/**
* returns true if the controller can run tests, false if not.
*
* @return bool
*/
abstract protected function canTest();
public function __construct()
{
$formatter = new OutputFormatter(true, self::createAdditionalStyles());
$this->output = new ConsoleOutput(ConsoleOutput::VERBOSITY_VERY_VERBOSE, true, $formatter);
}
/**
* Shows a console banner
*
* @param string $text
*/
protected function showBanner($text = 'testing')
{
$horizontalBorderWidth = 55;
$horizontalBorderSymbol = '#';
$verticalBorderSymbol = '#';
$borderThickness = 1;
$horizontalBorder = str_repeat($horizontalBorderSymbol, $horizontalBorderWidth);
$decoratedText = str_repeat($verticalBorderSymbol, $borderThickness).
str_pad($text, $horizontalBorderWidth - ($borderThickness * 2), ' ', STR_PAD_BOTH).
str_repeat($verticalBorderSymbol, $borderThickness);
for($index = 0; $index < $borderThickness; $index++) $this->output->writeln($horizontalBorder);
$this->output->writeln($decoratedText);
for($index = 0; $index < $borderThickness; $index++) $this->output->writeln($horizontalBorder);
}
/**
* Makes sure the application is in an predictable state (always the same).
*/
public function prepareEnvironment() {
$this->truncateDatabase();
}
/**
* Runs php unit tests
*
* @param string $type
* @return string The path to the php unit executable with filter or group parameters added an
* optionally with debug parameters added
*/
public function phpunit($type = 'kms') {
$this->showBanner('Starting '.$type.' unit tests');
$command = config('app.testing_php_binary').' -d display_errors=On -d memory_limit=768M '.base_path('vendor/bin/phpunit'); //Base phpunit command
$command .= ' -c '.$this->baseDirectory.'phpunit.xml --bootstrap vendor/autoload.php'; //Default parameters
$command .= ' --debug'; //Enable debug mode
$command .= $this->getCleanedCommandLineArguments($type, ['/--env\s?+=\s*\w+/']);
$this->output->writeln('Running command to test '.$type.': '.$command);
exec($command, $lines);
$this->output->writeln($lines);
}
/**
* Runs dusk (browser) tests
* @param string $type
*/
public function dusk($type = 'kms') {
$this->showBanner('Starting '.$type.' dusk tests');
$command = config('app.testing_php_binary').' artisan dusk '.$type;
$command .= ' --debug'; //Enable debug mode
$command .= $this->getCleanedCommandLineArguments($type);
$this->output->writeln('Running: '.$command);
exec($command, $output); //Artisan::call does not register helpers and other weird stuff happens when you use that instead.
$this->output->writeln($output);
$this->output->writeln('Browser tests done.');
}
/**
* Returns the command line arguments that work for phpunit / dusk
* @param string $testType
* @param array $extraRegexes
* @param bool $implode
* @return null|string|string[]
*/
public function getCleanedCommandLineArguments(string $testType, array $extraRegexes = [], $implode = true)
{
$commandLineArguments = $_SERVER['argv'];
//Define regexes that remove arguments that we don't want to pass trough to phpunit
$removeRegexes = array_merge([
'/artisan/',
'/'.$testType.':test/',
'/dusk/',
'/--noprep/',
'/kms/',
'/shop/',
'/unit/',
], $extraRegexes);
foreach($removeRegexes as $removeRegex) {
$commandLineArguments = preg_replace($removeRegex, '', $commandLineArguments);
}
return (!$implode) ? $commandLineArguments : implode(' ', $commandLineArguments);
}
/**
* Truncates the database. E.g deletes everything in the database
* @throws \Exception
*/
protected function truncateDatabase()
{
echo 'Truncating database: '.env('DB_DATABASE').PHP_EOL;
$tableNames = Schema::getConnection()->getDoctrineSchemaManager()->listTableNames();
Schema::disableForeignKeyConstraints();
foreach ($tableNames as $name) {
Schema::drop($name);
}
Schema::enableForeignKeyConstraints();
}
protected static function createAdditionalStyles()
{
return array(
'highlight' => new OutputFormatterStyle('red'),
'warning' => new OutputFormatterStyle('black', 'yellow'),
);
}
/**
* @param $parameters
* @return string
*/
protected static function parametersToString($parameters)
{
$parameterString = '';
foreach($parameters as $parameter => $value) {
if($value == '') {
$parameterString .= ' '.$parameter;
continue;
};
$parameterString .= sprintf(' %s=%s', $parameter, $value);
}
return trim($parameterString);
}
}