Skip to content

Commit a689e36

Browse files
committed
Write NEON manually, add test
1 parent c7f0729 commit a689e36

File tree

2 files changed

+83
-6
lines changed

2 files changed

+83
-6
lines changed

src/Drush/Commands/PhpstanDrupalDrushCommands.php

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace mglaman\PHPStanDrupal\Drush\Commands;
44

5-
use Drupal\Core\Serialization\Yaml;
65
use Drush\Commands\DrushCommands;
76

87
final class PhpstanDrupalDrushCommands extends DrushCommands
@@ -12,8 +11,10 @@ final class PhpstanDrupalDrushCommands extends DrushCommands
1211
* @command phpstan-drupal:setup
1312
* @option file
1413
* @bootstrap full
14+
*
15+
* @param array{file: string} $options
1516
*/
16-
public function setup($options = ['file' => null]): void
17+
public function setup(array $options = ['file' => '']): void
1718
{
1819
$parameters = [
1920
'level' => 2,
@@ -42,15 +43,34 @@ public function setup($options = ['file' => null]): void
4243
$config = [
4344
'parameters' => $parameters,
4445
];
45-
$output = Yaml::encode($config);
46-
// Replace 2 spaces with tabs for NEON compatibility.
47-
$output = str_replace(' ', "\t", $output);
46+
$output = rtrim($this->createNeon($config));
4847

49-
if ($options['file'] !== null) {
48+
if ($options['file'] !== '') {
5049
file_put_contents($options['file'], $output);
5150
} else {
5251
$this->io()->writeln($output);
5352
}
5453
}
5554

55+
private function createNeon(array $config, int $spacing = 0): string
56+
{
57+
$output = '';
58+
foreach ($config as $key => $value) {
59+
$indent = str_repeat("\t", $spacing);
60+
if (!is_array($value)) {
61+
$key = is_int($key) ? '- ' : "$key: ";
62+
if (!is_string($value)) {
63+
$value = \json_encode($value);
64+
}
65+
66+
$output .= "$indent$key" . $value . PHP_EOL;
67+
} elseif (count($value) === 0) {
68+
$output .= "$indent$key: []" . PHP_EOL;
69+
} else {
70+
$output .= "$indent$key:" . PHP_EOL;
71+
$output .= $this->createNeon($value, $spacing + 1);
72+
}
73+
}
74+
return $output;
75+
}
5676
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace mglaman\PHPStanDrupal\Tests\Drush\Commands;
4+
5+
use Drupal\Core\DependencyInjection\ContainerBuilder;
6+
use Drupal\Core\Entity\EntityTypeInterface;
7+
use Drupal\Core\Entity\EntityTypeManagerInterface;
8+
use Drupal\node\Entity\Node;
9+
use Drupal\node\NodeStorage;
10+
use mglaman\PHPStanDrupal\Drush\Commands\PhpstanDrupalDrushCommands;
11+
use PHPUnit\Framework\TestCase;
12+
use Symfony\Component\Console\Input\ArrayInput;
13+
use Symfony\Component\Console\Output\BufferedOutput;
14+
15+
final class PhpstanDrupalDrushCommandsTest extends TestCase
16+
{
17+
18+
public function testCreateNeon(): void
19+
{
20+
$container = new ContainerBuilder();
21+
22+
$etmMock = $this->createStub(EntityTypeManagerInterface::class);
23+
24+
$etdMock = $this->createStub(EntityTypeInterface::class);
25+
$etdMock->method('id')->willReturn('node');
26+
/** @phpstan-ignore-next-line */
27+
$etdMock->method('getClass')->willReturn(Node::class);
28+
/** @phpstan-ignore-next-line */
29+
$etdMock->method('getStorageClass')->willReturn(NodeStorage::class);
30+
31+
$etmMock->method('getDefinitions')->willReturn([
32+
'node' => $etdMock
33+
]);
34+
$container->set('entity_type.manager', $etmMock);
35+
\Drupal::setContainer($container);
36+
37+
$command = new PhpstanDrupalDrushCommands();
38+
$command->setInput(new ArrayInput([]));
39+
$output = new BufferedOutput();
40+
$command->setOutput($output);
41+
42+
$command->setup();
43+
self::assertEquals('parameters:
44+
level: 2
45+
paths:
46+
- web/modules/custom
47+
- web/themes/custom
48+
- web/profiles/custom
49+
drupal:
50+
entityMapping:
51+
node:
52+
class: Drupal\node\Entity\Node
53+
storage: Drupal\node\NodeStorage
54+
', $output->fetch());
55+
}
56+
57+
}

0 commit comments

Comments
 (0)