indentation: Fix indent-sequences in nested collections

When {spaces: consistent, indent-sequences: true} (the defaults),
and the expected indent for a block sequence that should be indented
is unknown, set the expected indent to an unknown value (-1) rather
than an arbitrary one (2). This ensures wrong-indentation is properly
caught when block sequences are nested.

Fixes issue #485
This commit is contained in:
Brian Brookman 2022-10-18 09:04:49 -07:00 committed by GitHub
parent 47cd8f2e9e
commit 764586d836
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 5 deletions

View File

@ -1370,6 +1370,45 @@ class IndentationTestCase(RuleTestCase):
' key: value\n' ' key: value\n'
'...\n', conf, problem=(2, 2)) '...\n', conf, problem=(2, 2))
def test_nested_collections_with_spaces_consistent(self):
"""Tests behavior of {spaces: consistent} in nested collections to
ensure wrong-indentation is properly caught--especially when the
expected indent value is initially unkown. For details, see
https://github.com/adrienverge/yamllint/issues/485.
"""
conf = ('indentation: {spaces: consistent,\n'
' indent-sequences: true}')
self.check('---\n'
'- item:\n'
' - elem\n'
'- item:\n'
' - elem\n'
'...\n', conf, problem=(3, 3))
conf = ('indentation: {spaces: consistent,\n'
' indent-sequences: false}')
self.check('---\n'
'- item:\n'
' - elem\n'
'- item:\n'
' - elem\n'
'...\n', conf, problem=(5,5))
conf = ('indentation: {spaces: consistent,\n'
' indent-sequences: consistent}')
self.check('---\n'
'- item:\n'
' - elem\n'
'- item:\n'
' - elem\n'
'...\n', conf, problem=(5,5))
conf = ('indentation: {spaces: consistent,\n'
' indent-sequences: whatever}')
self.check('---\n'
'- item:\n'
' - elem\n'
'- item:\n'
' - elem\n'
'...\n', conf)
def test_return(self): def test_return(self):
conf = 'indentation: {spaces: consistent}' conf = 'indentation: {spaces: consistent}'
self.check('---\n' self.check('---\n'

View File

@ -341,9 +341,14 @@ def _check(conf, token, prev, next, nextnext, context):
expected = detect_indent(expected, token) expected = detect_indent(expected, token)
if found_indentation != expected: if found_indentation != expected:
yield LintProblem(token.start_mark.line + 1, found_indentation + 1, if expected < 0:
'wrong indentation: expected %d but found %d' % message = 'wrong indentation: expected at least %d' % \
(expected, found_indentation)) (found_indentation + 1)
else:
message = 'wrong indentation: expected %d but found %d' % \
(expected, found_indentation)
yield LintProblem(token.start_mark.line + 1,
found_indentation + 1, message)
if (isinstance(token, yaml.ScalarToken) and if (isinstance(token, yaml.ScalarToken) and
conf['check-multi-line-strings']): conf['check-multi-line-strings']):
@ -493,8 +498,8 @@ def _check(conf, token, prev, next, nextnext, context):
# indentation it should have (because `spaces` is # indentation it should have (because `spaces` is
# `consistent` and its value has not been computed yet # `consistent` and its value has not been computed yet
# -- this is probably the beginning of the document). # -- this is probably the beginning of the document).
# So we choose an arbitrary value (2). # So we choose an unknown value (-1).
indent = 2 indent = -1
else: else:
indent = detect_indent(context['stack'][-1].indent, indent = detect_indent(context['stack'][-1].indent,
next) next)