class RuboCop::Cop::RSpec::ExcessiveDocstringSpacing


end
context ‘when a condition is met’ do
# good
end
context ‘ when a condition is met ’ do
# bad
@example
end
it ‘has excessive spacing’ do
# good
end
it ‘ has excessive spacing ’ do
# bad
@example
Checks for excessive whitespace in example descriptions.

def add_whitespace_offense(node, text)

Parameters:
  • text (String) --
  • node (RuboCop::AST::Node) --
def add_whitespace_offense(node, text)
  docstring = docstring(node)
  corrected = strip_excessive_whitespace(text)
  add_offense(docstring) do |corrector|
    corrector.replace(docstring, corrected)
  end
end

def docstring(node)

def docstring(node)
  expr = node.source_range
  Parser::Source::Range.new(
    expr.source_buffer,
    expr.begin_pos + 1,
    expr.end_pos - 1
  )
end

def excessive_whitespace?(text)

Parameters:
  • text (String) --
def excessive_whitespace?(text)
  text.match?(/
    # Leading space
    \A[[:blank:]]
    |
    # Trailing space
    [[:blank:]]\z
    |
    # Two or more consecutive spaces, except if they are leading spaces
    [^[[:space:]]][[:blank:]]{2,}[^[[:blank:]]]
  /x)
end

def on_send(node)

def on_send(node)
  example_description(node) do |description_node, message|
    return if description_node.heredoc?
    text = text(message)
    return unless excessive_whitespace?(text)
    add_whitespace_offense(description_node, text)
  end
end

def strip_excessive_whitespace(text)

Parameters:
  • text (String) --
def strip_excessive_whitespace(text)
  text
    .gsub(/[[:blank:]]{2,}/, ' ')
    .gsub(/\A[[:blank:]]|[[:blank:]]\z/, '')
end

def text(node)

that is the case for \-separated multiline strings with interpolation.
Recursive processing is required to process nested dstr nodes
def text(node)
  case node.type
  when :dstr
    node.node_parts.map { |child_node| text(child_node) }.join
  when :str, :sym
    node.value
  else
    node.source
  end
end