Skip to content

Commit

Permalink
Update master to output generated at f6986ea
Browse files Browse the repository at this point in the history
  • Loading branch information
abenevaut committed Apr 4, 2022
1 parent 4517f39 commit b0828a3
Show file tree
Hide file tree
Showing 30 changed files with 7,627 additions and 1 deletion.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.yml]
indent_style = space
indent_size = 2
7 changes: 7 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* text=auto
/.github export-ignore
.styleci.yml export-ignore
.scrutinizer.yml export-ignore
BACKERS.md export-ignore
CONTRIBUTING.md export-ignore
CHANGELOG.md export-ignore
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @abenevaut
5 changes: 5 additions & 0 deletions .github/CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Be free to fork this project.
All inspired code or re-used code have to be licensed to GNU GPLv3.
No contributions are accepted on this READ ONLY repository.

Roadmap: https://github.com/users/abenevaut/projects/9
3 changes: 3 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
No contributions are accepted on this READ ONLY repository.

Roadmap: https://github.com/users/abenevaut/projects/9
7 changes: 7 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
| Q | A |
| :--- | :---: |
| Do you experience this problem multiple times? | Yes / No |

## How to reproduce it ?

Explain here how to reproduce it ?
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
No contributions are accepted on this READ ONLY repository.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/vendor
/.idea
/.vscode
/.vagrant
.phpunit.result.cache
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# phpunit-slicer
# PHPUnit-slicer

Tool to slice PHPUnit tests files to tests suites.

## Install

```
composer require --dev abenevaut/phpunit-slicer
```
Empty file added app/Commands/.gitkeep
Empty file.
67 changes: 67 additions & 0 deletions app/Commands/SliceCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace App\Commands;

use App\Rules\DirectoryExistsRule;
use App\Rules\FileExistsRule;
use App\Services\PHPUnitConfigurationService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Validator;

class SliceCommand extends Command
{
/**
* The signature of the command.
*
* @var string
*/
protected $signature = 'slice {number-tests-suites : Number of tests suites to generate}
{phpunit-configuration : Path to phpunit.xml.dist (or phpunit.xml) to add generated tests suites}
{phpunit-configuration-destination : Path to save phpunit.xml with generated tests suites}
{tests-directory : Path to tests directory where to search tests. All tests should end with "Test.php"}';

/**
* The description of the command.
*
* @var string
*/
protected $description = 'Slice PHPUnit tests files to tests suites.';

/**
* @return int
* @throws \Illuminate\Validation\ValidationException
*/
public function handle()
{
$validator = Validator::make([
'number-tests-suites' => $this->argument('number-tests-suites'),
'phpunit-configuration' => $this->argument('phpunit-configuration'),
'phpunit-configuration-destination' => $this->argument('phpunit-configuration-destination'),
'tests-directory' => $this->argument('tests-directory'),
], [
'number-tests-suites' => 'integer|min:1',
'phpunit-configuration' => [new FileExistsRule],
'phpunit-configuration-destination' => 'required',
'tests-directory' => [new DirectoryExistsRule],
]
);

if ($validator->errors()->any() === true) {
foreach ($validator->errors()->all() as $errorMessage) {
$this->error($errorMessage);
}

return self::FAILURE;
}

resolve(PHPUnitConfigurationService::class)
->setConfigurationFile($validator->validate()['phpunit-configuration'])
->generateTestsSuites(
$validator->validate()['tests-directory'],
$validator->validate()['number-tests-suites']
)
->saveTo($validator->validate()['phpunit-configuration-destination']);

return self::SUCCESS;
}
}
28 changes: 28 additions & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}

/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
31 changes: 31 additions & 0 deletions app/Rules/DirectoryExistsRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\File;

class DirectoryExistsRule implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return File::isDirectory($value);
}

/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be a valid directory path.';
}
}
31 changes: 31 additions & 0 deletions app/Rules/FileExistsRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\File;

class FileExistsRule implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return File::exists($value);
}

/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be a valid file path.';
}
}
85 changes: 85 additions & 0 deletions app/Services/PHPUnitConfigurationService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace App\Services;

use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;

class PHPUnitConfigurationService
{
/**
* @var null|\DOMDocument
*/
private ?\DOMDocument $configurationFile = null;

/**
* @param string $configurationFile
*
* @return $this
*/
public function setConfigurationFile(string $configurationFile): self
{
$this->configurationFile = new \DOMDocument();
$this->configurationFile->load($configurationFile);

return $this;
}

/**
* @param string $testsDirectory
* @param int $numberTestsSuites
*
* @return $this
* @throws \DOMException
* @throws \Throwable
*/
public function generateTestsSuites(string $testsDirectory, int $numberTestsSuites = 4)
{
throw_if(!$this->isInitialized(), new \Exception('Configuration file is not set.'));

$testSuites = $this->configurationFile->createElement('testsuites');

collect(File::allFiles($testsDirectory))
->filter(function (string $file) {
return Str::contains($file, 'Test.php');
})
->split($numberTestsSuites)
->each(function ($filesList, $index) use ($testSuites) {
$testSuite = $this->configurationFile->createElement('testsuite');
$testSuite->setAttribute('name', "sliced-testsuite-{$index}");

collect($filesList)
->each(function ($file) use ($testSuite) {
$testSuite->appendChild($this->configurationFile->createElement('file', $file));
});

$testSuites->appendChild($testSuite);
});

$phpunit = $this->configurationFile->getElementsByTagName('phpunit')->item(0);
$phpunit->replaceChild($testSuites, $phpunit->getElementsByTagName('testsuites')->item(0));

return $this;
}

/**
* @param string $destination
*
* @return false|int
* @throws \Throwable
*/
public function saveTo(string $destination)
{
throw_if(!$this->isInitialized(), new \Exception('Configuration file is not set.'));

return $this->configurationFile->save($destination);
}

/**
* @return bool
*/
private function isInitialized(): bool
{
return $this->configurationFile instanceof \DOMDocument;
}
}
50 changes: 50 additions & 0 deletions bootstrap/app.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/

$app = new LaravelZero\Framework\Application(
dirname(__DIR__)
);

/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/

$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
LaravelZero\Framework\Kernel::class
);

$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
Illuminate\Foundation\Exceptions\Handler::class
);

/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/

return $app;
20 changes: 20 additions & 0 deletions box.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"chmod": "0755",
"directories": [
"app",
"bootstrap",
"config",
"lang",
"vendor"
],
"exclude-dev-files": false,
"files": [
"composer.json"
],
"exclude-composer-files": false,
"compression": "GZ",
"compactors": [
"KevinGH\\Box\\Compactor\\Php",
"KevinGH\\Box\\Compactor\\Json"
]
}
Binary file added builds/phpunit-slicer
Binary file not shown.
Loading

0 comments on commit b0828a3

Please sign in to comment.