/** {@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); }
/** * @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); }
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; } } }
/** * @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; }
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'); } }
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'); } }
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); }
/** {@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); }
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']]; }
public function testCustomSearchStrategy() { $editor = $this->container->get('redaktilo.editor'); $text = Text::fromString(''); // Should not throw \Gnugat\Redaktilo\Search\PatternNotSupportedException $editor->hasBelow($text, false); }
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.']]; }
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']]; }
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()); }
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'); } } }
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']]; }
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); } } }
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']]; }
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']]; }
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.']]; }
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']]; }
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']]; }
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']]; }
private function printLine(Text $file, $lineNumber) { $line = $file->getLine($lineNumber - 1); $this->output->writeln('<comment>[' . $lineNumber . ']</comment> "' . $line . '"'); }
/** * @param Text $text * * @return string */ public function make(Text $text) { return implode($text->getLineBreak(), $text->getLines()); }