From 7cb7b4f6690eaeaa0f39103e838b6456cb544c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Sun, 31 Jan 2016 20:09:40 +0100 Subject: [PATCH] Rules: commas: Add 'min-spaces-after' Since such constructions are allowed and valid YAML: - [one,two, three,four] this commit adds a `min-spaces-after` option that defaults to 1. --- tests/rules/test_commas.py | 158 +++++++++++++++++++++++++++---------- yamllint/conf/default.yml | 1 + yamllint/rules/commas.py | 48 +++++++++-- 3 files changed, 160 insertions(+), 47 deletions(-) diff --git a/tests/rules/test_commas.py b/tests/rules/test_commas.py index 4f51e8b..97cc08d 100644 --- a/tests/rules/test_commas.py +++ b/tests/rules/test_commas.py @@ -33,9 +33,25 @@ class CommaTestCase(RuleTestCase): ' key2: val2,\n' '}\n' '...\n', conf) + self.check('---\n' + '- [one, two , three,four]\n' + '- {five,six , seven, eight}\n' + '- [\n' + ' nine, ten\n' + ' , eleven\n' + ' ,twelve\n' + ']\n' + '- {\n' + ' thirteen: 13, fourteen\n' + ' , fifteen: 15\n' + ' ,sixteen: 16\n' + '}\n', conf) - def test_before_enabled(self): - conf = 'commas: {max-spaces-before: 0, max-spaces-after: -1}' + def test_before_max(self): + conf = ('commas:\n' + ' max-spaces-before: 0\n' + ' min-spaces-after: 0\n' + ' max-spaces-after: -1\n') self.check('---\n' 'array: [1, 2, 3, 4]\n' '...\n', conf) @@ -75,8 +91,51 @@ class CommaTestCase(RuleTestCase): ' key2: val2 ,\n' '}\n', conf, problem=(4, 13)) - def test_before_max(self): - conf = 'commas: {max-spaces-before: 3, max-spaces-after: -1}' + def test_before_max_with_comma_on_new_line(self): + conf = ('commas:\n' + ' max-spaces-before: 0\n' + ' min-spaces-after: 0\n' + ' max-spaces-after: -1\n') + self.check('---\n' + 'flow-seq: [1, 2, 3\n' + ' , 4, 5, 6]\n' + '...\n', conf, problem=(3, 11)) + self.check('---\n' + 'flow-map: {a: 1, b: 2\n' + ' , c: 3}\n' + '...\n', conf, problem=(3, 11)) + + conf = ('commas:\n' + ' max-spaces-before: 0\n' + ' min-spaces-after: 0\n' + ' max-spaces-after: -1\n' + 'indentation: disable\n') + self.check('---\n' + 'flow-seq: [1, 2, 3\n' + ' , 4, 5, 6]\n' + '...\n', conf, problem=(3, 9)) + self.check('---\n' + 'flow-map: {a: 1, b: 2\n' + ' , c: 3}\n' + '...\n', conf, problem=(3, 9)) + self.check('---\n' + '[\n' + '1,\n' + '2\n' + ', 3\n' + ']\n', conf, problem=(5, 1)) + self.check('---\n' + '{\n' + 'a: 1,\n' + 'b: 2\n' + ', c: 3\n' + '}\n', conf, problem=(5, 1)) + + def test_before_max_3(self): + conf = ('commas:\n' + ' max-spaces-before: 3\n' + ' min-spaces-after: 0\n' + ' max-spaces-after: -1\n') self.check('---\n' 'array: [1 , 2, 3 , 4]\n' '...\n', conf) @@ -90,8 +149,32 @@ class CommaTestCase(RuleTestCase): ' key: val,\n' ']\n', conf, problem=(4, 11)) - def test_after_enabled(self): - conf = 'commas: {max-spaces-before: -1, max-spaces-after: 1}' + def test_after_min(self): + conf = ('commas:\n' + ' max-spaces-before: -1\n' + ' min-spaces-after: 1\n' + ' max-spaces-after: -1\n') + self.check('---\n' + '- [one, two , three,four]\n' + '- {five,six , seven, eight}\n' + '- [\n' + ' nine, ten\n' + ' , eleven\n' + ' ,twelve\n' + ']\n' + '- {\n' + ' thirteen: 13, fourteen\n' + ' , fifteen: 15\n' + ' ,sixteen: 16\n' + '}\n', conf, + problem1=(2, 21), problem2=(3, 9), + problem3=(7, 4), problem4=(12, 4)) + + def test_after_max(self): + conf = ('commas:\n' + ' max-spaces-before: -1\n' + ' min-spaces-after: 0\n' + ' max-spaces-after: 1\n') self.check('---\n' 'array: [1, 2, 3, 4]\n' '...\n', conf) @@ -124,8 +207,11 @@ class CommaTestCase(RuleTestCase): ' key1: val1, key2: [val2, val3]\n' '}\n', conf, problem1=(3, 16), problem2=(3, 30)) - def test_after_max(self): - conf = 'commas: {max-spaces-before: -1, max-spaces-after: 3}' + def test_after_max_3(self): + conf = ('commas:\n' + ' max-spaces-before: -1\n' + ' min-spaces-after: 1\n' + ' max-spaces-after: 3\n') self.check('---\n' 'array: [1, 2, 3, 4]\n' '...\n', conf) @@ -137,7 +223,10 @@ class CommaTestCase(RuleTestCase): '...\n', conf, problem1=(2, 31), problem2=(2, 49)) def test_both_before_and_after(self): - conf = 'commas: {max-spaces-before: 0, max-spaces-after: 1}' + conf = ('commas:\n' + ' max-spaces-before: 0\n' + ' min-spaces-after: 1\n' + ' max-spaces-after: 1\n') self.check('---\n' 'dict: {a: b , c: "1 2 3", d: e , f: [g, h]}\n' 'array: [\n' @@ -152,36 +241,25 @@ class CommaTestCase(RuleTestCase): problem1=(2, 12), problem2=(2, 16), problem3=(2, 31), problem4=(2, 36), problem5=(2, 50), problem6=(4, 8), problem7=(5, 11), problem8=(8, 13)) - - def test_comma_on_new_line(self): - conf = 'commas: {max-spaces-before: 0, max-spaces-after: 1}' - self.check('---\n' - 'flow-seq: [1, 2, 3\n' - ' , 4, 5, 6]\n' - '...\n', conf, problem=(3, 11)) - self.check('---\n' - 'flow-map: {a: 1, b: 2\n' - ' , c: 3}\n' - '...\n', conf, problem=(3, 11)) - conf = ('commas: {max-spaces-before: 0, max-spaces-after: 1}\n' + conf = ('commas:\n' + ' max-spaces-before: 0\n' + ' min-spaces-after: 1\n' + ' max-spaces-after: 1\n' 'indentation: disable\n') self.check('---\n' - 'flow-seq: [1, 2, 3\n' - ' , 4, 5, 6]\n' - '...\n', conf, problem=(3, 9)) - self.check('---\n' - 'flow-map: {a: 1, b: 2\n' - ' , c: 3}\n' - '...\n', conf, problem=(3, 9)) - self.check('---\n' - '[\n' - '1,\n' - '2\n' - ', 3\n' - ']\n', conf, problem=(5, 1)) - self.check('---\n' - '{\n' - 'a: 1,\n' - 'b: 2\n' - ', c: 3\n' - '}\n', conf, problem=(5, 1)) + '- [one, two , three,four]\n' + '- {five,six , seven, eight}\n' + '- [\n' + ' nine, ten\n' + ' , eleven\n' + ' ,twelve\n' + ']\n' + '- {\n' + ' thirteen: 13, fourteen\n' + ' , fifteen: 15\n' + ' ,sixteen: 16\n' + '}\n', conf, + problem1=(2, 12), problem2=(2, 21), problem3=(3, 9), + problem4=(3, 12), problem5=(5, 9), problem6=(6, 2), + problem7=(7, 2), problem8=(7, 4), problem9=(10, 17), + problem10=(11, 2), problem11=(12, 2), problem12=(12, 4)) diff --git a/yamllint/conf/default.yml b/yamllint/conf/default.yml index 7d72570..2b5aa3c 100644 --- a/yamllint/conf/default.yml +++ b/yamllint/conf/default.yml @@ -12,6 +12,7 @@ rules: max-spaces-after: 1 commas: max-spaces-before: 0 + min-spaces-after: 1 max-spaces-after: 1 comments: level: warning diff --git a/yamllint/rules/commas.py b/yamllint/rules/commas.py index 28997ee..386e6cb 100644 --- a/yamllint/rules/commas.py +++ b/yamllint/rules/commas.py @@ -21,12 +21,14 @@ Use this rule to control the number of spaces before and after commas (``,``). * ``max-spaces-before`` defines the maximal number of spaces allowed before commas (use ``-1`` to disable). +* ``min-spaces-after`` defines the minimal number of spaces required after + commas. * ``max-spaces-after`` defines the maximal number of spaces allowed after commas (use ``-1`` to disable). .. rubric:: Examples -#. With ``commas: {max-spaces-before: 0, max-spaces-after: 1}`` +#. With ``commas: {max-spaces-before: 0}`` the following code snippet would **PASS**: :: @@ -40,25 +42,53 @@ Use this rule to control the number of spaces before and after commas (``,``). strange var: [10, 20 , 30, {x: 1, y: 2}] - the following code snippet would **FAIL**: +#. With ``commas: {max-spaces-before: 2}`` + + the following code snippet would **PASS**: :: strange var: - [10, 20, 30, {x: 1, y: 2}] + [10 , 20 , 30, {x: 1 , y: 2}] -#. With ``commas: {max-spaces-before: 2, max-spaces-after: 2}`` +#. With ``commas: {max-spaces-before: -1}`` the following code snippet would **PASS**: :: strange var: - [10 , 20 , 30, {x: 1 , y: 2}] + [10, + 20 , 30 + , {x: 1, y: 2}] + +#. With ``commas: {min-spaces-after: 1, max-spaces-after: 1}`` + + the following code snippet would **PASS**: + :: + + strange var: + [10, 20,30, {x: 1, y: 2}] the following code snippet would **FAIL**: :: strange var: - [10 , 20 , 30, {x: 1 , y: 2}] + [10, 20,30, {x: 1, y: 2}] + +#. With ``commas: {min-spaces-after: 1, max-spaces-after: 3}`` + + the following code snippet would **PASS**: + :: + + strange var: + [10, 20, 30, {x: 1, y: 2}] + +#. With ``commas: {min-spaces-after: 0, max-spaces-after: 1}`` + + the following code snippet would **PASS**: + :: + + strange var: + [10, 20,30, {x: 1, y: 2}] """ @@ -71,12 +101,14 @@ from yamllint.rules.common import spaces_after, spaces_before ID = 'commas' TYPE = 'token' CONF = {'max-spaces-before': int, + 'min-spaces-after': int, 'max-spaces-after': int} def check(conf, token, prev, next, context): if isinstance(token, yaml.FlowEntryToken): - if prev is not None and prev.end_mark.line < token.start_mark.line: + if (prev is not None and conf['max-spaces-before'] != -1 and + prev.end_mark.line < token.start_mark.line): yield LintProblem(token.start_mark.line + 1, max(1, token.start_mark.column), 'too many spaces before comma') @@ -88,7 +120,9 @@ def check(conf, token, prev, next, context): yield problem problem = spaces_after(token, prev, next, + min=conf['min-spaces-after'], max=conf['max-spaces-after'], + min_desc='too few spaces after comma', max_desc='too many spaces after comma') if problem is not None: yield problem