quoted-strings: Fix broken rule

Original implementation was completely broken. Documentation and actual
behavior were different. Numbers and booleans were detected as wrong, as
well as explicit types.

Fixes #136 and #130.
This commit is contained in:
Adrien Vergé
2018-10-16 18:47:26 +02:00
parent 524d721f0d
commit 8354d50016
2 changed files with 51 additions and 48 deletions

View File

@@ -34,19 +34,19 @@ class QuotedTestCase(RuleTestCase):
def test_quote_type_any(self): def test_quote_type_any(self):
conf = 'quoted-strings: {quote-type: any}\n' conf = 'quoted-strings: {quote-type: any}\n'
self.check('---\n' self.check('---\n'
'string1: "foo"\n' 'boolean1: true\n'
'number1: 123\n' # fails 'number1: 123\n'
'string2: foo\n' # fails 'string1: foo\n' # fails
'string2: "foo"\n'
'string3: \'bar\'\n' 'string3: \'bar\'\n'
'string4: !!str genericstring\n' # fails 'string4: !!str genericstring\n'
'string5: !!str 456\n' # fails 'string5: !!str 456\n'
'string6: !!str "quotedgenericstring"\n' 'string6: !!str "quotedgenericstring"\n'
'binary: !!binary binstring\n' 'binary: !!binary binstring\n'
'integer: !!int intstring\n' 'integer: !!int intstring\n'
'boolean1: !!bool boolstring\n' 'boolean2: !!bool boolstring\n'
'boolean2: !!bool "quotedboolstring"\n', 'boolean3: !!bool "quotedboolstring"\n',
conf, problem1=(3, 10), problem2=(4, 10), conf, problem=(4, 10))
problem3=(6, 16), problem4=(7, 16))
self.check('---\n' self.check('---\n'
'multiline string 1: |\n' 'multiline string 1: |\n'
' line 1\n' ' line 1\n'
@@ -65,19 +65,19 @@ class QuotedTestCase(RuleTestCase):
def test_quote_type_single(self): def test_quote_type_single(self):
conf = 'quoted-strings: {quote-type: single}\n' conf = 'quoted-strings: {quote-type: single}\n'
self.check('---\n' self.check('---\n'
'string1: "foo"\n' # fails 'boolean1: true\n'
'number1: 123\n' # fails 'number1: 123\n'
'string2: foo\n' # fails 'string1: foo\n' # fails
'string2: "foo"\n' # fails
'string3: \'bar\'\n' 'string3: \'bar\'\n'
'string4: !!str genericstring\n' # fails 'string4: !!str genericstring\n'
'string5: !!str 456\n' # fails 'string5: !!str 456\n'
'string6: !!str "quotedgenericstring"\n' # fails 'string6: !!str "quotedgenericstring"\n'
'binary: !!binary binstring\n' 'binary: !!binary binstring\n'
'integer: !!int intstring\n' 'integer: !!int intstring\n'
'boolean1: !!bool boolstring\n' 'boolean2: !!bool boolstring\n'
'boolean2: !!bool "quotedboolstring"\n', 'boolean3: !!bool "quotedboolstring"\n',
conf, problem1=(2, 10), problem2=(3, 10), problem3=(4, 10), conf, problem1=(4, 10), problem2=(5, 10))
problem4=(6, 16), problem5=(7, 16), problem6=(8, 16))
self.check('---\n' self.check('---\n'
'multiline string 1: |\n' 'multiline string 1: |\n'
' line 1\n' ' line 1\n'
@@ -96,19 +96,19 @@ class QuotedTestCase(RuleTestCase):
def test_quote_type_double(self): def test_quote_type_double(self):
conf = 'quoted-strings: {quote-type: double}\n' conf = 'quoted-strings: {quote-type: double}\n'
self.check('---\n' self.check('---\n'
'string1: "foo"\n' 'boolean1: true\n'
'number1: 123\n' # fails 'number1: 123\n'
'string2: foo\n' # fails 'string1: foo\n' # fails
'string2: "foo"\n'
'string3: \'bar\'\n' # fails 'string3: \'bar\'\n' # fails
'string4: !!str genericstring\n' # fails 'string4: !!str genericstring\n'
'string5: !!str 456\n' # fails 'string5: !!str 456\n'
'string6: !!str "quotedgenericstring"\n' 'string6: !!str "quotedgenericstring"\n'
'binary: !!binary binstring\n' 'binary: !!binary binstring\n'
'integer: !!int intstring\n' 'integer: !!int intstring\n'
'boolean1: !!bool boolstring\n' 'boolean2: !!bool boolstring\n'
'boolean2: !!bool "quotedboolstring"\n', 'boolean3: !!bool "quotedboolstring"\n',
conf, problem1=(3, 10), problem2=(4, 10), problem3=(5, 10), conf, problem1=(4, 10), problem2=(6, 10))
problem4=(6, 16), problem5=(7, 16))
self.check('---\n' self.check('---\n'
'multiline string 1: |\n' 'multiline string 1: |\n'
' line 1\n' ' line 1\n'

View File

@@ -16,8 +16,8 @@
""" """
Use this rule to forbid any string values that are not quoted. Use this rule to forbid any string values that are not quoted.
You can also enforce the type of the quote used - single or double - using the You can also enforce the type of the quote used using the ``quote-type`` option
``quote-type`` option. (``single``, ``double`` or ``any``).
**Note**: Multi-line strings (with ``|`` or ``>``) will not be checked. **Note**: Multi-line strings (with ``|`` or ``>``) will not be checked.
@@ -51,24 +51,27 @@ CONF = {'quote-type': ('any', 'single', 'double')}
def check(conf, token, prev, next, nextnext, context): def check(conf, token, prev, next, nextnext, context):
quote_type = conf['quote-type'] quote_type = conf['quote-type']
if prev and isinstance(prev, yaml.tokens.TagToken): if (isinstance(token, yaml.tokens.ScalarToken) and
if prev.value[1] != "str": isinstance(prev, (yaml.ValueToken, yaml.TagToken))):
# we ignore generic strings, e.g. somestring: !!str testtest # Ignore explicit types, e.g. !!str testtest or !!int 42
if (prev and isinstance(prev, yaml.tokens.TagToken) and
prev.value[0] == '!!'):
return return
if isinstance(token, yaml.tokens.ScalarToken): # Ignore numbers, booleans, etc.
if isinstance(prev, yaml.tokens.ValueToken) or \ resolver = yaml.resolver.Resolver()
isinstance(prev, yaml.tokens.TagToken): if resolver.resolve(yaml.nodes.ScalarNode, token.value,
if ((not token.plain) and (True, False)) != 'tag:yaml.org,2002:str':
((token.style == "|") or (token.style == ">"))): return
# we ignore multi-line strings
return
if ((quote_type == 'single' and token.style != "'") or # Ignore multi-line strings
(quote_type == 'double' and token.style != '"') or if (not token.plain) and (token.style == "|" or token.style == ">"):
(quote_type == 'any' and token.style is None)): return
yield LintProblem(
token.start_mark.line + 1, if ((quote_type == 'single' and token.style != "'") or
token.start_mark.column + 1, (quote_type == 'double' and token.style != '"') or
"string value is not quoted with %s quotes" % (quote_type) (quote_type == 'any' and token.style is None)):
) yield LintProblem(
token.start_mark.line + 1,
token.start_mark.column + 1,
"string value is not quoted with %s quotes" % (quote_type))