Skip to content

Commit 7842a8f

Browse files
committed
Adding assertion to the indentation cleaning
1 parent 00faf8f commit 7842a8f

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

spec/Mamazu/DocumentationParser/Validator/Yaml/YamlValidatorSpec.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,17 @@ public function it_validates_indented_block(Parser $parser, Block $block): void
8282

8383
$this->validate($block)->shouldHaveCount(0);
8484
}
85+
86+
public function it_validates_a_strangely_indented_block(Parser $parser, Block $block): void
87+
{
88+
$block->getFileName()->willReturn('readme.md');
89+
$block->getRelativeLineNumber()->willReturn(10);
90+
$block->getContent()->willReturn(<<<YAML
91+
fixtures:
92+
testing: 1234
93+
YAML);
94+
95+
$this->shouldThrow(new \InvalidArgumentException('Expected indentation "\t" in file readme.md on line 11'))
96+
->during('validate', [$block]);
97+
}
8598
}

src/Validator/Yaml/YamlValidator.php

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function __construct(?Parser $parser = null)
2121

2222
public function validate(Block $block): array
2323
{
24-
$cleanedContent = $this->normalizeIndentation($block->getContent());
24+
$cleanedContent = $this->normalizeIndentation($block);
2525
try {
2626
$this->parser->parse($cleanedContent);
2727
} catch (ParseException $exception) {
@@ -33,31 +33,55 @@ public function validate(Block $block): array
3333
return [];
3434
}
3535

36-
private function normalizeIndentation(string $content): string
36+
private function normalizeIndentation(Block $block): string
3737
{
38-
$lineContent = explode("\n", $content);
39-
$offset = 0;
38+
$lineContent = explode("\n", $block->getContent());
39+
$indendation = '';
4040
foreach ($lineContent as $line) {
4141
if ($line === '') {
4242
continue;
4343
}
4444

45+
$offset = 0;
4546
while ($offset < strlen($line)) {
4647
$char = $line[$offset];
4748
if (! ctype_space($char)) {
4849
break;
4950
}
5051
$offset++;
5152
}
53+
$indendation = substr($line, 0, $offset);
54+
5255
break;
5356
}
5457

55-
return implode(
56-
"\n",
57-
array_map(
58-
static fn (string $line): string => substr($line, $offset),
59-
$lineContent
60-
)
61-
);
58+
// Speed up if there is no indentation.
59+
if ($indendation === '') {
60+
return $block->getContent();
61+
}
62+
63+
$result = '';
64+
foreach ($lineContent as $lineIndex => $line) {
65+
$count = 1;
66+
if (strpos($line, $indendation) !== 0) {
67+
$trueLineNumber = $block->getRelativeLineNumber() + $lineIndex;
68+
throw new \InvalidArgumentException(
69+
sprintf(
70+
'Expected indentation "%s" in file %s on line %d',
71+
$this->printIndentation($indendation),
72+
$block->getFileName(),
73+
$trueLineNumber
74+
)
75+
);
76+
}
77+
$result = str_replace($indendation, '', $line, $count) . PHP_EOL;
78+
}
79+
80+
return $result;
81+
}
82+
83+
private function printIndentation(string $indentation): string
84+
{
85+
return str_replace(["\t", ' '], ['\\t', ''], $indentation);
6286
}
6387
}

0 commit comments

Comments
 (0)