Skip to content

Commit

Permalink
New rule: Ensure link are at the bottom of the file (#1542)
Browse files Browse the repository at this point in the history
  • Loading branch information
alamirault authored Oct 16, 2023
1 parent fe70dd2 commit d30f700
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* [ensure_bash_prompt_before_composer_command](#ensure_bash_prompt_before_composer_command)
* [ensure_exactly_one_space_before_directive_type](#ensure_exactly_one_space_before_directive_type)
* [ensure_exactly_one_space_between_link_definition_and_link](#ensure_exactly_one_space_between_link_definition_and_link)
* [ensure_link_bottom](#ensure_link_bottom)
* [ensure_link_definition_contains_valid_url](#ensure_link_definition_contains_valid_url)
* [ensure_order_of_code_blocks_in_configuration_block](#ensure_order_of_code_blocks_in_configuration_block)
* [ensure_php_reference_syntax](#ensure_php_reference_syntax)
Expand Down Expand Up @@ -356,6 +357,12 @@ composer require symfony/var-dumper
.. _DOCtor-RST: https://github.com/OskarStark/DOCtor-RST
```

## `ensure_link_bottom`

> _Ensure link lines are at the bottom of the file._
#### Groups [`@Symfony`]

## `ensure_link_definition_contains_valid_url`

> _Ensure link definition contains valid link._
Expand Down
66 changes: 66 additions & 0 deletions src/Rule/EnsureLinkBottom.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

/**
* This file is part of DOCtor-RST.
*
* (c) Oskar Stark <oskarstark@googlemail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace App\Rule;

use App\Attribute\Rule\Description;
use App\Rst\RstParser;
use App\Value\Lines;
use App\Value\NullViolation;
use App\Value\RuleGroup;
use App\Value\Violation;
use App\Value\ViolationInterface;

#[Description('Ensure link lines are at the bottom of the file.')]
class EnsureLinkBottom extends AbstractRule implements LineContentRule
{
public static function getGroups(): array
{
return [RuleGroup::Symfony()];
}

public function check(Lines $lines, int $number, string $filename): ViolationInterface
{
$lines->seek($number);
$line = $lines->current();

if (!RstParser::isLinkDefinition($line)) {
return NullViolation::create();
}

while ($lines->valid()) {
$lines->next();

if (!$lines->valid()) {
break;
}

$current = $lines->current();

if ($current->isBlank()) {
continue;
}

if (!RstParser::isLinkDefinition($current)) {
return Violation::from(
'Please move link definition to the bottom of the page',
$filename,
$number + 1,
$line,
);
}
}

return NullViolation::create();
}
}
94 changes: 94 additions & 0 deletions tests/Rule/EnsureLinkBottomTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

/**
* This file is part of DOCtor-RST.
*
* (c) Oskar Stark <oskarstark@googlemail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace App\Tests\Rule;

use App\Rule\EnsureLinkBottom;
use App\Tests\RstSample;
use App\Tests\UnitTestCase;
use App\Value\NullViolation;
use App\Value\Violation;
use App\Value\ViolationInterface;

final class EnsureLinkBottomTest extends UnitTestCase
{
/**
* @test
*
* @dataProvider checkProvider
*/
public function check(ViolationInterface $expected, RstSample $sample): void
{
self::assertEquals(
$expected,
(new EnsureLinkBottom())->check($sample->lines, $sample->lineNumber, 'filename'),
);
}

/**
* @return \Generator<array{0: ViolationInterface, 1: RstSample}>
*/
public static function checkProvider(): iterable
{
yield [
NullViolation::create(),
new RstSample('temp'),
];

yield [
NullViolation::create(),
new RstSample([
'',
'.. _`first-link`: https://foo.bar',
], 1),
];

yield [
NullViolation::create(),
new RstSample([
'',
'.. _`first-link`: https://foo.bar',
'.. _`second-link`: https://foo.baz',
], 1),
];

yield [
Violation::from(
'Please move link definition to the bottom of the page',
'filename',
2,
'.. _`first-link`: https://foo.bar',
),
new RstSample([
'',
'.. _`first-link`: https://foo.bar',
'text after link',
], 1),
];

yield [
Violation::from(
'Please move link definition to the bottom of the page',
'filename',
2,
'.. _`first-link`: https://foo.bar',
),
new RstSample([
'',
'.. _`first-link`: https://foo.bar',
'',
'text after link',
], 1),
];
}
}

0 comments on commit d30f700

Please sign in to comment.