Rules: indentation: Rewrite algorithm

pull/4/head
Adrien Vergé 9 years ago
parent 3989a09d32
commit e81b73c111

@ -41,8 +41,8 @@ class ColonTestCase(RuleTestCase):
' - o: {k1: v1}\n' ' - o: {k1: v1}\n'
' - p: kdjf\n' ' - p: kdjf\n'
' - q: val0\n' ' - q: val0\n'
' q2:\n' ' - q2:\n'
' - val1\n' ' - val1\n'
'...\n', conf) '...\n', conf)
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
@ -66,8 +66,8 @@ class ColonTestCase(RuleTestCase):
' val\n' ' val\n'
' - o: {k1: v1}\n' ' - o: {k1: v1}\n'
' - o: {k1: v1}\n' ' - o: {k1: v1}\n'
' q2:\n' ' - q2:\n'
' - val1\n' ' - val1\n'
'...\n', conf) '...\n', conf)
self.check('---\n' self.check('---\n'
'a: {b: {c: d, e : f}}\n', conf) 'a: {b: {c: d, e : f}}\n', conf)

@ -118,7 +118,7 @@ class IndentationTestCase(RuleTestCase):
self.check('---\n' self.check('---\n'
' object:\n' ' object:\n'
' val: 1\n' ' val: 1\n'
'...\n', conf, problem=(2, 2)) '...\n', conf, problem1=(2, 2), problem2=(3, 6))
self.check('---\n' self.check('---\n'
'- el1\n' '- el1\n'
'- el2:\n' '- el2:\n'
@ -132,8 +132,9 @@ class IndentationTestCase(RuleTestCase):
self.check('---\n' self.check('---\n'
' - el1\n' ' - el1\n'
' - el2:\n' ' - el2:\n'
' - subel\n' ' - subel\n'
'...\n', conf, problem1=(2, 3), problem2=(4, 7)) '...\n', conf,
problem1=(2, 3), problem2=(3, 3), problem3=(4, 5))
def test_multi_lines(self): def test_multi_lines(self):
self.check('---\n' self.check('---\n'
@ -154,18 +155,32 @@ class IndentationTestCase(RuleTestCase):
'...\n', None) '...\n', None)
def test_nested_collections(self): def test_nested_collections(self):
conf = 'indentation: {spaces: 2}'
self.check('---\n'
'- o:\n'
' k1: v1\n'
'...\n', conf)
self.check('---\n'
'- o:\n'
' k1: v1\n'
'...\n', conf, problem=(3, 2))
self.check('---\n'
'- o:\n'
' k1: v1\n'
'...\n', conf, problem=(3, 4))
conf = 'indentation: {spaces: 4}'
self.check('---\n' self.check('---\n'
'- o:\n' '- o:\n'
' k1: v1\n' ' k1: v1\n'
'...\n', None) '...\n', conf)
self.check('---\n' self.check('---\n'
'- o:\n' '- o:\n'
' k1: v1\n' ' k1: v1\n'
'...\n', None, problem=(3, 4)) '...\n', conf, problem=(3, 4))
self.check('---\n' self.check('---\n'
'- o:\n' '- o:\n'
' k1: v1\n' ' k1: v1\n'
'...\n', None, problem=(3, 6)) '...\n', conf, problem=(3, 6))
def test_return(self): def test_return(self):
self.check('---\n' self.check('---\n'
@ -189,3 +204,23 @@ class IndentationTestCase(RuleTestCase):
# ' c:\n' # ' c:\n'
# ' d:\n' # ' d:\n'
# '...\n', None, problem=(5, 2)) # '...\n', None, problem=(5, 2))
def test_first_line(self):
conf = ('indentation: {spaces: 2}\n'
'document-start: disable\n')
self.check(' a: 1\n', conf, problem=(1, 3))
def test_broken_inline_flows(self):
conf = 'indentation: {spaces: 2}'
self.check('---\n'
'obj: {\n'
' a: 1,\n'
' b: 2,\n'
' c: 3\n'
'}\n', conf, problem1=(4, 4), problem2=(5, 2))
self.check('---\n'
'list: [\n'
' 1,\n'
' 2,\n'
' 3\n'
']\n', conf, problem1=(4, 4), problem2=(5, 2))

@ -25,39 +25,46 @@ CONF = {'spaces': int}
def check(conf, token, prev, next): def check(conf, token, prev, next):
if isinstance(token, yaml.StreamEndToken): if isinstance(token, (yaml.StreamStartToken, yaml.StreamEndToken)):
return return
if (prev is None or isinstance(prev, yaml.StreamStartToken) or # Check if first token in line
isinstance(prev, yaml.DirectiveToken) or if (not isinstance(prev, (yaml.StreamStartToken, yaml.DirectiveToken)) and
isinstance(prev, yaml.DocumentStartToken)): token.start_mark.line == prev.end_mark.line):
if token.start_mark.column != 0:
yield LintProblem(
token.end_mark.line + 1, token.start_mark.column + 1,
'found indentation of %d instead of %d' %
(token.start_mark.column, 0))
return return
if token.start_mark.line > prev.end_mark.line: if token.start_mark.column % conf['spaces'] != 0:
buffer = prev.end_mark.buffer yield LintProblem(
token.end_mark.line + 1, token.start_mark.column + 1,
'indentation is not a multiple of %d' % conf['spaces'])
return
if isinstance(prev, (yaml.StreamStartToken,
yaml.DirectiveToken,
yaml.DocumentStartToken,
yaml.DocumentEndToken)):
indent = 0
else:
buffer = prev.end_mark.buffer
start = buffer.rfind('\n', 0, prev.end_mark.pointer) + 1 start = buffer.rfind('\n', 0, prev.end_mark.pointer) + 1
prev_indent = 0
# YAML recognizes two white space characters: space and tab. indent = 0
# http://yaml.org/spec/1.2/spec.html#id2775170 while buffer[start + indent] == ' ':
while buffer[start + prev_indent] in ' \t': indent += 1
prev_indent += 1
# Discard any leading '- ' if token.start_mark.column > indent:
if (buffer[start + prev_indent:start + prev_indent + 2] == '- '): if not isinstance(prev, (yaml.BlockSequenceStartToken,
prev_indent += 2 yaml.BlockMappingStartToken,
while buffer[start + prev_indent] in ' \t': yaml.FlowSequenceStartToken,
prev_indent += 1 yaml.FlowMappingStartToken,
yaml.KeyToken,
yaml.ValueToken)):
yield LintProblem(
token.end_mark.line + 1, token.start_mark.column + 1,
'unexpected indentation')
if (token.start_mark.column > prev_indent and elif token.start_mark.column != indent + conf['spaces']:
token.start_mark.column != prev_indent + conf['spaces']):
yield LintProblem( yield LintProblem(
token.end_mark.line + 1, token.start_mark.column + 1, token.end_mark.line + 1, token.start_mark.column + 1,
'found indentation of %d instead of %d' % 'found indentation of %d instead of %d' %
(token.start_mark.column, prev_indent + conf['spaces'])) (token.start_mark.column, indent + conf['spaces']))

Loading…
Cancel
Save