Skip to content

Commit 1728a37

Browse files
committed
t1
1 parent d49e615 commit 1728a37

22 files changed

+1495
-9
lines changed

.scaffold/Customizer.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Composer\Script\Event;
6+
7+
/**
8+
* Class to setup drupal scaffold extension right way.
9+
*/
10+
class Customizer {
11+
12+
/**
13+
* Working directory.
14+
*
15+
* @var string
16+
*/
17+
protected string $workingDir;
18+
19+
/**
20+
* IO composer.
21+
*/
22+
protected $io;
23+
24+
public static function customize(Event $event): void {
25+
$customizer = new self($event->getIO());
26+
27+
try {
28+
$customizer->run();
29+
}
30+
catch (\Exception $e) {
31+
print $e->getMessage() . PHP_EOL;
32+
exit ($e->getCode());
33+
}
34+
}
35+
36+
public function __construct($io) {
37+
$this->io = $io;
38+
}
39+
40+
public function run() {
41+
$this->workingDir = dirname(__DIR__);
42+
$this->showProgress('Started customizer');
43+
}
44+
45+
protected function showProgress($section) {
46+
$this->io->write('<info>' . $section . '</info>');
47+
}
48+
49+
}

.scaffold/CustomizerOld.php

Lines changed: 463 additions & 0 deletions
Large diffs are not rendered by default.

.scaffold/tests/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/node_modules
22
/coverage
3+
/vendor
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":1,"defects":{"Drupal\\drupal_extension_scaffold\\Tests\\Functional\\ScaffoldCreateProjectTest::testCreateProjectNoInstall":8,"Drupal\\drupal_extension_scaffold\\Tests\\Functional\\ScaffoldCreateProjectTest::testCreateProjectInstall":8},"times":[]}

.scaffold/tests/composer.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "alexskrypnyk/drupal_extension_scaffold_test",
3+
"type": "project",
4+
"license": "GPL-2.0-or-later",
5+
"require": {
6+
"php": ">=8.2"
7+
},
8+
"require-dev": {
9+
"composer/composer": "^2.7",
10+
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
11+
"helmich/phpunit-json-assert": "^2.0",
12+
"phpcompatibility/php-compatibility": "^9.3",
13+
"phpmd/phpmd": "^2.15",
14+
"phpstan/phpstan": "^1.10",
15+
"phpunit/phpunit": "^11.1",
16+
"rector/rector": "^1.0",
17+
"symfony/filesystem": "^6.0",
18+
"symfony/finder": "^6.0",
19+
"symfony/process": "^6.4"
20+
},
21+
"autoload-dev":{
22+
"psr-4":{
23+
"Drupal\\drupal_extension_scaffold\\Tests\\": "phpunit"
24+
}
25+
},
26+
"config": {
27+
"allow-plugins": {
28+
"dealerdirect/phpcodesniffer-composer-installer": true
29+
}
30+
}
31+
}

.scaffold/tests/phpunit.xml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
cacheDirectory=".phpunit.cache"
6+
executionOrder="depends,defects"
7+
requireCoverageMetadata="false"
8+
beStrictAboutCoverageMetadata="false"
9+
beStrictAboutOutputDuringTests="true"
10+
failOnRisky="true"
11+
failOnWarning="true"
12+
displayDetailsOnTestsThatTriggerWarnings="true"
13+
displayDetailsOnTestsThatTriggerErrors="true"
14+
displayDetailsOnTestsThatTriggerNotices="true"
15+
>
16+
<testsuites>
17+
<testsuite name="default">
18+
<directory>phpunit</directory>
19+
</testsuite>
20+
</testsuites>
21+
22+
<coverage includeUncoveredFiles="true"
23+
pathCoverage="false"
24+
ignoreDeprecatedCodeUnits="true"
25+
disableCodeCoverageIgnore="false">
26+
<report>
27+
<html outputDirectory=".coverage-html" lowUpperBound="50" highLowerBound="90"/>
28+
<cobertura outputFile="cobertura.xml"/>
29+
</report>
30+
</coverage>
31+
</phpunit>

.scaffold/tests/phpunit/Dirs.php

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
namespace Drupal\drupal_extension_scaffold\Tests;
4+
5+
use Drupal\drupal_extension_scaffold\Tests\Traits\FileTrait;
6+
use Symfony\Component\Filesystem\Filesystem;
7+
8+
/**
9+
*
10+
*/
11+
class Dirs {
12+
13+
use FileTrait;
14+
15+
/**
16+
* Directory where a copy of the DrevOps Scaffold repository is located.
17+
*
18+
* This allows to isolate the test from this repository files and prevent
19+
* their accidental removal.
20+
*
21+
* @var string
22+
*/
23+
public $repo;
24+
25+
/**
26+
* Root build directory where the rest of the directories located.
27+
*
28+
* The "build" in this context is a place to store assets produced by a single
29+
* test run.
30+
*
31+
* @var string
32+
*/
33+
public $build;
34+
35+
/**
36+
* Directory where the test will run.
37+
*
38+
* @var string
39+
*/
40+
public $sut;
41+
42+
/**
43+
* The file system.
44+
*/
45+
protected Filesystem $fs;
46+
47+
public function __construct() {
48+
$this->fs = new Filesystem();
49+
}
50+
51+
public function initLocations(): void {
52+
$this->build = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'drevops-scaffold-' . microtime(TRUE);
53+
$this->sut = $this->build . '/sut';
54+
$this->repo = $this->build . '/local_repo';
55+
56+
$this->fs->mkdir($this->build);
57+
58+
$this->prepareLocalRepo();
59+
}
60+
61+
public function deleteLocations(): void {
62+
$this->fs->remove($this->build);
63+
}
64+
65+
public function printInfo(): void {
66+
$lines[] = '-- LOCATIONS --';
67+
$lines[] = 'Build : ' . $this->build;
68+
$lines[] = 'SUT : ' . $this->sut;
69+
$lines[] = 'Local repo : ' . $this->repo;
70+
71+
fwrite(STDERR, PHP_EOL . implode(PHP_EOL, $lines) . PHP_EOL);
72+
}
73+
74+
protected function prepareLocalRepo(): void {
75+
$root = $this->fileFindDir('composer.json');
76+
77+
$this->fs->copy($root . '/composer.json', $this->repo . '/composer.json');
78+
$this->fs->mirror($root . '/scripts', $this->repo . '/scripts');
79+
$this->fs->mirror($root . '/.circleci', $this->repo . '/.circleci');
80+
$this->fs->copy($root . '/myfile1.txt', $this->repo . '/myfile1.txt');
81+
82+
// Add the local repository to the composer.json file.
83+
$composerjson = file_get_contents($this->repo . '/composer.json');
84+
if ($composerjson === FALSE) {
85+
throw new \Exception('Failed to read the local composer.json file.');
86+
}
87+
88+
/** @var array $dst_json */
89+
$dst_json = json_decode($composerjson, TRUE);
90+
if (!$dst_json) {
91+
throw new \Exception('Failed to decode the local composer.json file.');
92+
}
93+
94+
$dst_json['repositories'][] = [
95+
'type' => 'path',
96+
'url' => $this->repo,
97+
'options' => [
98+
'symlink' => FALSE,
99+
],
100+
];
101+
file_put_contents($this->repo . '/composer.json', json_encode($dst_json, JSON_PRETTY_PRINT));
102+
}
103+
104+
}

.scaffold/tests/phpunit/Fixtures/.gitkeep

Whitespace-only changes.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Drupal\drupal_extension_scaffold\Tests\Functional;
4+
5+
/**
6+
* @coversDefaultClass Customizer
7+
*/
8+
class ScaffoldCreateProjectTest extends ScaffoldTestCase {
9+
10+
public function testCreateProjectNoInstall(): void {
11+
$output = $this->composerRun($this->composerCreateProject('--no-install'));
12+
//
13+
$this->assertStringContainsString('Started customizer', $output);
14+
// $this->assertStringContainsString('Initialised project from DrevOps Scaffold', $output);
15+
// $this->assertStringContainsString('Run `composer install` to further customise the project', $output);
16+
//
17+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.name', ScaffoldGeneralizer::PROJECT_NAME);
18+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.require-dev."drevops/scaffold"', "@dev");
19+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.scripts."pre-update-cmd"[1]', ScaffoldScriptHandler::class . '::preUpdateCmd');
20+
// $this->assertJsonHasNoKey($this->composerReadJson(), '$.scripts."post-root-package-install"[1]');
21+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.extra."drupal-scaffold"."allowed-packages"[0]', ScaffoldGeneralizer::DREVOPS_SCAFFOLD_NAME);
22+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.autoload.classmap[0]', 'scripts/composer/ScaffoldScriptHandler.php');
23+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.autoload.classmap[1]', 'scripts/composer/ScriptHandler.php');
24+
}
25+
26+
public function testCreateProjectInstall(): void {
27+
$output = $this->composerRun($this->composerCreateProject());
28+
$this->assertStringContainsString('Started customizer', $output);
29+
//
30+
// $this->assertStringContainsString('Initialised project from DrevOps Scaffold', $output);
31+
// $this->assertStringNotContainsString('Run `composer install` to further customise the project', $output);
32+
//
33+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.name', ScaffoldGeneralizer::PROJECT_NAME);
34+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.require-dev."drevops/scaffold"', "@dev");
35+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.scripts."pre-update-cmd"[1]', ScaffoldScriptHandler::class . '::preUpdateCmd');
36+
// $this->assertJsonHasNoKey($this->composerReadJson(), '$.scripts."post-root-package-install"[1]');
37+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.extra."drupal-scaffold"."allowed-packages"[0]', ScaffoldGeneralizer::DREVOPS_SCAFFOLD_NAME);
38+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.autoload.classmap[0]', 'scripts/composer/ScaffoldScriptHandler.php');
39+
// $this->assertJsonValueEquals($this->composerReadJson(), '$.autoload.classmap[1]', 'scripts/composer/ScriptHandler.php');
40+
}
41+
42+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Drupal\drupal_extension_scaffold\Tests\Functional;
6+
7+
use Drupal\drupal_extension_scaffold\Tests\Dirs;
8+
use Drupal\drupal_extension_scaffold\Tests\Traits\CmdTrait;
9+
use Drupal\drupal_extension_scaffold\Tests\Traits\ComposerTrait;
10+
use Drupal\drupal_extension_scaffold\Tests\Traits\EnvTrait;
11+
use Drupal\drupal_extension_scaffold\Tests\Traits\JsonAssertTrait;
12+
use PHPUnit\Framework\TestCase;
13+
use PHPUnit\Framework\TestStatus\Failure;
14+
use Symfony\Component\Filesystem\Filesystem;
15+
16+
/**
17+
*
18+
*/
19+
class ScaffoldTestCase extends TestCase {
20+
21+
use CmdTrait;
22+
use ComposerTrait;
23+
use EnvTrait;
24+
use JsonAssertTrait;
25+
26+
/**
27+
* @var \Symfony\Component\Filesystem\Filesystem
28+
*/
29+
protected $fs;
30+
31+
/**
32+
* @var \Drupal\drupal_extension_scaffold\Tests\Dirs
33+
*/
34+
protected $dirs;
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
protected function setUp(): void {
40+
parent::setUp();
41+
42+
$this->fs = new Filesystem();
43+
44+
$this->dirs = new Dirs();
45+
$this->dirs->initLocations();
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*/
51+
protected function tearDown(): void {
52+
if (!$this->hasFailed()) {
53+
$this->dirs->deleteLocations();
54+
}
55+
56+
parent::tearDown();
57+
}
58+
59+
/**
60+
* {@inheritdoc}
61+
*/
62+
protected function onNotSuccessfulTest(\Throwable $t): never {
63+
$this->dirs->printInfo();
64+
65+
// Rethrow the exception to allow the test to fail normally.
66+
parent::onNotSuccessfulTest($t);
67+
}
68+
69+
public function hasFailed(): bool {
70+
$status = $this->status();
71+
72+
return $status instanceof Failure;
73+
}
74+
75+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Drupal\drupal_extension_scaffold\Tests\Traits;
4+
5+
/**
6+
* Trait ArrayTrait.
7+
*
8+
* Provides methods for working with arrays.
9+
*/
10+
trait ArrayTrait {
11+
12+
/**
13+
* Recursively replace a value in the array using provided callback.
14+
*
15+
* @param array $array
16+
* The array to process.
17+
* @param callable $cb
18+
* The callback to use.
19+
*
20+
* @return array
21+
* The processed array.
22+
*/
23+
public static function arrayReplaceValue(array $array, callable $cb): array {
24+
foreach ($array as $k => $item) {
25+
$array[$k] = is_array($item) ? static::arrayReplaceValue($item, $cb) : $cb($item);
26+
}
27+
28+
return $array;
29+
}
30+
31+
}

0 commit comments

Comments
 (0)