Пример #1
0
 /** {@inheritdoc} */
 public function findBelow(Text $text, $pattern, $location = null)
 {
     $location = (null !== $location ? $location : $text->getCurrentLineNumber()) + 1;
     $lines = $text->getLines();
     $belowLines = array_slice($lines, $location, null, true);
     return $this->findIn($belowLines, $pattern);
 }
Пример #2
0
 /**
  * @return int One of the result constants
  */
 public function handle(ConstraintViolationListInterface $constraintViolationList, Text $file)
 {
     $diff = null;
     if ($file instanceof File) {
         foreach ($this->diff as $d) {
             if (substr($d->getTo(), 2) === $file->getFilename()) {
                 $diff = $d;
                 break;
             }
         }
         if (null === $diff) {
             return Reporter::SUCCESS;
         }
     }
     foreach ($constraintViolationList as $offset => $violation) {
         /** @var ConstraintViolation $violation */
         $lineNumber = $this->getLineNumber($violation);
         foreach ($diff->getChunks() as $chunk) {
             if ($chunk->getEnd() > $lineNumber || $chunk->getEnd() + $chunk->getEndRange() < $lineNumber) {
                 $constraintViolationList->remove($offset);
             }
         }
     }
     return $this->reporter->handle($constraintViolationList, $file);
 }
Пример #3
0
 public function reviewLine($line, $lineNumber, Text $file)
 {
     if (preg_match('/^([\\~\\!\\"\\#\\$\\%\\&\'\\(\\)\\*\\+,-.\\\\\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\_\\`\\{\\|\\}])\\1{3,}$/', trim($line), $data)) {
         $character = $data[1];
         $level = array_search($character, $this->levels);
         if (false === $level) {
             $this->addError('Only =, -, ~, . and " should be used as title underlines');
             return;
         }
         // .inc files are allowed to start with a deeper level.
         $isIncludedFile = $file instanceof File && preg_match('/\\.inc/', $file->getFilename());
         if ($isIncludedFile && !$this->startLevelIsDetermined) {
             $this->startLevelIsDetermined = true;
             $this->currentLevel = $level;
         }
         if ($level <= $this->currentLevel) {
             $this->currentLevel = $level;
             return;
         }
         if ($this->currentLevel + 1 !== $level) {
             $this->addError('The "%underline_char%" character should be used for a title level %level%', array('%underline_char%' => $this->levels[$this->currentLevel + 1], '%level%' => $this->currentLevel + 1));
         } else {
             $this->currentLevel = $level;
         }
     }
 }
Пример #4
0
 /**
  * @param Text $text
  *
  * @return array
  */
 public function from(Text $text)
 {
     $lines = $text->getLines();
     $lineBreak = $text->getLineBreak();
     $content = implode($lineBreak, $lines);
     $rawTokens = token_get_all($content);
     return $this->tokenBuilder->buildFromRaw($rawTokens);
 }
 function let(TextSanitizer $textSanitizer, LocationSanitizer $locationSanitizer, Text $text)
 {
     $this->rootPath = __DIR__ . '/../../../../../';
     $filename = sprintf(self::ORIGINAL_FILENAME, $this->rootPath);
     $lines = file($filename, FILE_IGNORE_NEW_LINES);
     $text->getLines()->willReturn($lines);
     $this->beConstructedWith($textSanitizer, $locationSanitizer);
 }
 function it_finds_relatively_to_the_first_line(Text $text)
 {
     $pattern = '/\\[Sniggering\\]/';
     $lineNumber = 5;
     $text->getCurrentLineNumber()->shouldNotBeCalled();
     $this->findAbove($text, $pattern, 0)->shouldBe(false);
     $this->findBelow($text, $pattern, 0)->shouldBe($lineNumber);
 }
 /** {@inheritdoc} */
 public function findBelow(Text $text, $pattern, $location = null)
 {
     trigger_error(__CLASS__ . ' has been replaced by Text#setCurrentLineNumber', \E_USER_DEPRECATED);
     $foundLineNumber = (null !== $location ? $location : $text->getCurrentLineNumber()) + $pattern;
     if (0 > $foundLineNumber || $foundLineNumber >= $text->getLength()) {
         return false;
     }
     return $foundLineNumber;
 }
Пример #8
0
 public function reviewLine($line, $lineNumber, Text $file)
 {
     // exception to the rule: The Quick Tour and Best Practices sections are allowed to use the first person.
     if ($file instanceof File && preg_match('/^(?:quick_tour|best_practices)/', $file->getFilename())) {
         return;
     }
     if (preg_match('/\\b(I(?!\\.)|we|let\'s)\\b/i', $line)) {
         $this->addError('The first person ("I", "we", "let\'s") should always be avoided');
     }
 }
Пример #9
0
 public function reviewLine($line, $lineNumber, Text $file)
 {
     if (0 === strlen($line)) {
         return;
     }
     if (rtrim($line) !== $line) {
         $this->addError('There should be no trailing whitespace at the end of a line');
     } elseif (preg_match('/[\\w.]\\s{2,}\\w/', $line) && !preg_match('/^[\\w=]+$/', $file->getLine($line + 1))) {
         $this->addError('This line contains successive whitespaces');
     }
 }
Пример #10
0
 public function reviewLine($line, $lineNumber, Text $file)
 {
     if (preg_match('/^(^[\\~\\!\\"\\#\\$\\%\\&\'\\(\\)\\*\\+,-.\\\\\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\_\\`\\{\\|\\}])\\1{3,}$/', trim($line))) {
         if ($lineNumber === 0) {
             return;
         }
         $titleText = $file->getLine($lineNumber - 1);
         if (strlen(trim($titleText)) !== strlen(trim($line))) {
             $this->addError('The underline of a title should have exact the same length as the text of the title');
         }
     }
 }
 function it_converts_file_content_into_php_tokens(TokenBuilder $tokenBuilder, Text $text)
 {
     $rootPath = __DIR__ . '/../../../../../';
     $filename = sprintf(self::FILENAME, $rootPath);
     $content = file_get_contents($filename);
     $lineBreak = StringUtil::detectLineBreak($content);
     $lines = explode($lineBreak, $content);
     $rawTokens = token_get_all($content);
     $text->getLineBreak()->willReturn($lineBreak);
     $text->getLines()->willReturn($lines);
     $tokenBuilder->buildFromRaw($rawTokens)->willReturn(array());
     $this->from($text);
 }
Пример #12
0
 /** {@inheritdoc} */
 public function findBelow(Text $text, $pattern, $location = null)
 {
     trigger_error(__CLASS__ . ' is no longer supported and will be removed in version 2', \E_USER_DEPRECATED);
     $location = (null !== $location ? $location : $text->getCurrentLineNumber()) + 1;
     $tokens = $this->converter->from($text);
     $total = count($tokens);
     for ($index = 0; $index < $total; $index++) {
         $token = $tokens[$index];
         if ($token->getLineNumber() === $location) {
             break;
         }
     }
     return $this->findIn($tokens, $index, $pattern);
 }
 /**
  * @param mixed $pattern
  * @param Text  $text
  */
 public function __construct($pattern, Text $text)
 {
     $this->pattern = $pattern;
     $this->text = $text;
     $patternMessage = 'given pattern';
     if (is_string($pattern) || is_int($pattern)) {
         $patternMessage .= ' "' . strval($pattern) . '"';
     }
     $textMessage = 'the given text';
     if ($text instanceof File) {
         $textMessage = 'the given file ' . $text->getFilename();
     }
     $message = sprintf('The %s couldn\'t be find in %s', $patternMessage, $textMessage);
     parent::__construct($message);
 }
Пример #14
0
    public function getExamples()
    {
        $message = 'The short syntax for PHP code (::) should be used here';
        return [[Text::fromString(<<<RST
A line ending with a nice colon:

.. code-block:: php

    echo 'You failed!';
RST
), [$this->getViolationProphet($message, 3)]], [Text::fromString(<<<RST
A line ending without a colon.

.. code-block:: php

    echo 'Correct!';

And one with::

.. code-block:: php

    echo 'You failed!';

And another good usage::

    echo 'Yes, you passed!';

At last:

.. code-block:: ruby

    puts 'You\\'re a good documentor!';
RST
), [$this->getViolationProphet($message, 3)], 'When ending with a colon, the shorthand should be used for PHP code blocks']];
    }
Пример #15
0
 public function testCustomSearchStrategy()
 {
     $editor = $this->container->get('redaktilo.editor');
     $text = Text::fromString('');
     // Should not throw \Gnugat\Redaktilo\Search\PatternNotSupportedException
     $editor->hasBelow($text, false);
 }
Пример #16
0
    public function getExamples()
    {
        $message = 'All words, except from closed-class words, have to be capitalized: "%s"';
        return [[Text::fromString(<<<RST
A wrong capitalized title of A section
==========================
RST
), [$this->getViolationProphet(sprintf($message, 'A Wrong Capitalized Title of a Section'), 1)], 'All words should be capitalized, except from closed-class ones.']];
    }
Пример #17
0
    public function getExamples()
    {
        $message = 'The first person ("I", "we", "let\'s") should always be avoided';
        return [[Text::fromString('I wrote this line!'), [$this->getViolationProphet($message, 1)], 'The usage of I is not allowed'], [Text::fromString(<<<RST
Let's make things worse...
and let's not improve it on this line.
RST
), [$this->getViolationProphet($message, 1), $this->getViolationProphet($message, 2)], 'The usage of let\'s is not allowed'], [Text::fromString('We are writing this line together...'), [$this->getViolationProphet($message, 1)], 'The usage of we is not allowed']];
    }
Пример #18
0
 public function reviewLine($line, $lineNumber, Text $file)
 {
     if (preg_match('/^\\s*\\.\\. ([\\w-]+)::|::$/', $line, $data)) {
         $nextLine = $file->getLine($lineNumber + 1);
         if (isset($data[1]) && 'versionadded' === $data[1]) {
             if (trim($nextLine) === '') {
                 $this->addError('There should be no empty line between the start of a versionadded directive and the body', array(), $lineNumber + 3);
             }
             return;
         }
         if (':' === substr(trim($nextLine), 0, 1) || isset($data[1]) && 'index' === $data[1]) {
             return;
         }
         if (trim($nextLine) !== '') {
             $this->addError('There should be an empty line between the body and the start of a directive (except from versionadded directives)', array(), $lineNumber + 2);
         }
     }
 }
 /** {@inheritDoc} */
 public function execute(array $input)
 {
     $text = $this->textSanitizer->sanitize($input);
     $pattern = $input['pattern'];
     $replacement = $input['replacement'];
     $content = $this->contentFactory->make($text);
     $replacedContent = preg_replace($pattern, $replacement, $content);
     $replacedText = Text::fromString($replacedContent);
     $text->setLines($replacedText->getLines());
 }
Пример #20
0
 public function reviewLine($line, $lineNumber, Text $file)
 {
     if ('.. code-block:: php' === trim($line)) {
         $lineBefore = null;
         $lineBeforeNumber = $lineNumber;
         while ($lineBeforeNumber > 0) {
             $lineBefore = $file->getLine(--$lineBeforeNumber);
             if (trim($lineBefore) !== '') {
                 break;
             }
         }
         if (null === $lineBefore) {
             return;
         }
         if (preg_match('/:$/', rtrim($lineBefore))) {
             $this->addError('The short syntax for PHP code (::) should be used here');
         }
     }
 }
Пример #21
0
    public function getExamples()
    {
        $message = 'There should be a space between "%s" and "%s".';
        return [[Text::fromString(<<<RST
:ref:`a label<the_reference>`
:ref:`other label <correct_reference>`
RST
), [$this->getViolationProphet(sprintf($message, 'a label', '<the_reference>'), 1)], 'Ref roles must have a space between label and reference'], [Text::fromString(<<<RST
:doc:`a label<the_reference>`
:doc:`other label <correct_reference>`
RST
), [$this->getViolationProphet(sprintf($message, 'a label', '<the_reference>'), 1)], 'Doc roles must have a space between label and reference']];
    }
Пример #22
0
 public function reviewLine($line, $lineNumber, Text $file)
 {
     if (preg_match('/^([\\~\\!\\"\\#\\$\\%\\&\'\\(\\)\\*\\+,-.\\\\\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\_\\`\\{\\|\\}])\\1{3,}$/', trim($line))) {
         if ($lineNumber === 0) {
             return;
         }
         $titleText = trim($file->getLine($lineNumber - 1));
         $words = explode(' ', $titleText);
         if (count($words) === 1) {
             return;
         }
         $correctTitle = '';
         $nextShouldBeCapitialized = false;
         foreach ($words as $word) {
             $wordIsInClosedClass = in_array(strtolower($word), self::$closedClassWords);
             if (!$nextShouldBeCapitialized && $wordIsInClosedClass) {
                 // lowercase
                 $correctTitle .= strtolower($word[0]) . substr($word, 1);
             } else {
                 // capitialize
                 $correctTitle .= ucfirst($word);
             }
             if (in_array(substr($correctTitle, -1), array(':', '.'))) {
                 $nextShouldBeCapitialized = true;
             } else {
                 $nextShouldBeCapitialized = false;
             }
             $correctTitle .= ' ';
         }
         $correctTitle = trim(ucfirst($correctTitle));
         if (ucfirst($correctTitle) !== $titleText) {
             // exception: field type references start with a lowercase word
             if (preg_match('/^[a-z]+ Field Type$/', trim($titleText))) {
                 return;
             }
             $this->addError('All words, except from closed-class words, have to be capitalized: "%correct_title%"', array('%correct_title%' => $correctTitle), $lineNumber);
         }
     }
 }
Пример #23
0
    public function getExamples()
    {
        $message = 'The underline of a title should have exact the same length as the text of the title';
        return [[Text::fromString(<<<RST
A title
====
RST
), [$this->getViolationProphet($message, 2)], 'Underlines that are too short are invalid'], [Text::fromString(<<<RST
A title
===========
RST
), [$this->getViolationProphet($message, 2)], 'Underlines that are too long are invalid']];
    }
Пример #24
0
    public function getExamples()
    {
        $message = 'There should be no trailing whitespace at the end of a line';
        return [[Text::fromString(<<<RST
a file with just normal text
     
followed by nasty trailing whitespace

and a simple empty line.
RST
), [$this->getViolationProphet($message, 2)], 'Lines which contain only whitespace are not allowed'], [Text::fromString(<<<RST
a line with whitespace after it     
a tab is also whitespace\t
RST
), [$this->getViolationProphet($message, 1), $this->getViolationProphet($message, 2)], 'Whitespace at the end of a line is not allowed']];
    }
Пример #25
0
    public function getExamples()
    {
        $message = 'The "%s" directive is not styled on symfony.com';
        return [[Text::fromString(<<<RST
.. warning::

    I am stoffing you!

.. caution::

    Yes, prefect.

.. danger::

    I may put a comment on each line of your PR
RST
), [$this->getViolationProphet(sprintf($message, 'warning'), 1), $this->getViolationProphet(sprintf($message, 'danger'), 10)], 'Usage of unstyled directives is not allowed.']];
    }
Пример #26
0
    public function getExamples()
    {
        $message = 'There should be an empty line between the body and the start of a directive (except from versionadded directives)';
        return [[Text::fromString(<<<RST
.. note::
    The contents of the note.

.. code-block::

    // correct!
RST
), [$this->getViolationProphet($message, 1)], 'Admonitions started with `.. xxx::` require a blank line'], [Text::fromString(<<<RST
Let's try one more time::
    // come on, you know better...
RST
), [$this->getViolationProphet($message, 1)], 'Code blocks started with `::` require a blank line'], [Text::fromString(<<<RST
.. versionadded:: 2.5
    Do you know what was added in 2.5?

.. versionadded:: 2.5

    Do you know what was added in 2.5?
RST
), [$this->getViolationProphet('There should be no empty line between the start of a versionadded directive and the body', 4)], 'Version added directive should not have a blank line'], [Text::fromString(<<<RST
.. code-block:: php
    :linenums:

    // some code!
RST
), [], 'Directive options are allowed to be placed directly after the start'], [Text::fromString(<<<RST
.. index::
    single: Hello

.. index::

    single: Hello
RST
), [], 'Index directives do not require a blank line']];
    }
Пример #27
0
    public function getExamples()
    {
        $levelMessage = 'The "%s" character should be used for a title level %d';
        $invalidMessage = 'Only =, -, ~, . and " should be used as title underlines';
        $incFile = File::fromString(<<<RST
Title level 3
~~~~~~~~~~~~~
RST
);
        $incFile->setFilename('file.rst.inc');
        return [[Text::fromString(<<<RST
Title Level 1
=============

Title level 2
~~~~~~~~~~~~~
RST
), [$this->getViolationProphet(sprintf($levelMessage, '-', 2), 2)], 'It finds wrongly used underline level'], [Text::fromString(<<<RST
Title Level 1
+++++++++++++
RST
), [$this->getViolationProphet($invalidMessage, 2)], 'It finds unused underline levels that are valid in reStructured Text'], [Text::fromString(<<<RST
Title level 1
=============

Title level 2
-------------

Title level 3
~~~~~~~~~~~~~

Title level 4
.............

Title level 2
-------------
RST
), [], 'It accepts jumping multiple levels back'], [$incFile, [], 'Inc files are allowed to start at deeper levels']];
    }
Пример #28
0
    public function getExamples()
    {
        $proseMessage = 'A line should be wrapped after the first word that crosses the 72th character';
        $codeMessage = 'In order to avoid horizontal scrollbars, you should wrap the code on a 85 character limit';
        return [[Text::fromString(<<<RST
A line that does not reach the limit
A line that goes over the limit with a lot of words, as you can see in this sentence...
RST
), [$this->getViolationProphet($proseMessage, 2)], 'Prose lines should not have new words after the 72th character'], [Text::fromString('Tetaumatawhakatangihangakoauaotamateaurehaeaturipukapihimaungahoronukupokaiwhenuaakitanatahu'), [], 'Long words are allowed to have more than 72 characters'], [Text::fromString('**type**: ``string`` **default**: ``This is a long constraint error message, but it should be allowed.``'), [], 'Definitions are allowed to cross 72 characters'], [Text::fromString(<<<RST
.. code-block:: php

    // a line that is around 80 characters long, so there should not be an error here
    // but this should error, as it is longer than 80 characters long. Oh dear, what did I do?

Same applies to::

    // a line that is around 80 characters long, so there should not be an error here
    // but this should error, as it is longer than 80 characters long. Oh dear, what did I do?
RST
), [$this->getViolationProphet($codeMessage, 4), $this->getViolationProphet($codeMessage, 9)], 'Code uses a limit for 85 characters'], [Text::fromString(<<<RST
    .. code-block:: php

        // a line that is around 80 characters long, so there should not be an error here
            // the same line, but now indented, so that it should give us this very nice error
RST
), [$this->getViolationProphet($codeMessage, 4)], 'Indentation should be stripped from code blocks'], [Text::fromString(<<<RST
.. code-block:: xml

    <?xml version="1.0" encoding="UTF-8"?>
    <srv:container xmlns="http://symfony.com/schema/dic/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:srv="http://symfony.com/schema/dic/services"
        xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    </srv:container>
RST
), [], 'XML schemaLocation definitions are allowed to cross the 85 character limit']];
    }
Пример #29
0
 private function printLine(Text $file, $lineNumber)
 {
     $line = $file->getLine($lineNumber - 1);
     $this->output->writeln('<comment>[' . $lineNumber . ']</comment> "' . $line . '"');
 }
Пример #30
0
 /**
  * @param Text $text
  *
  * @return string
  */
 public function make(Text $text)
 {
     return implode($text->getLineBreak(), $text->getLines());
 }