From a5b384ab21ddc0e8f498f2fc9c550f67971e2729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Wed, 13 Jan 2016 17:56:07 +0100 Subject: [PATCH] Rules: Add the 'commas' rule --- tests/rules/test_commas.py | 154 +++++++++++++++++++++++++++++++++++++ yamllint/conf/default.yml | 6 +- yamllint/rules/__init__.py | 2 + yamllint/rules/commas.py | 38 +++++++++ 4 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 tests/rules/test_commas.py create mode 100644 yamllint/rules/commas.py diff --git a/tests/rules/test_commas.py b/tests/rules/test_commas.py new file mode 100644 index 0000000..09fe578 --- /dev/null +++ b/tests/rules/test_commas.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016 Adrien Vergé +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from tests.rules.common import RuleTestCase + + +class CommaTestCase(RuleTestCase): + rule_id = 'commas' + + def test_disabled(self): + conf = 'commas: disable' + self.check('---\n' + 'dict: {a: b , c: "1 2 3", d: e , f: [g, h]}\n' + 'array: [\n' + ' elem ,\n' + ' key: val ,\n' + ']\n' + 'map: {\n' + ' key1: val1 ,\n' + ' key2: val2,\n' + '}\n' + '...\n', conf) + + def test_before_enabled(self): + conf = 'commas: {max-spaces-before: 0, max-spaces-after: -1}' + self.check('---\n' + 'array: [1, 2, 3, 4]\n' + '...\n', conf) + self.check('---\n' + 'array: [1, 2 , 3, 4]\n' + '...\n', conf, problem=(2, 13)) + self.check('---\n' + 'array: [1 , 2, 3 , 4]\n' + '...\n', conf, problem1=(2, 10), problem2=(2, 23)) + self.check('---\n' + 'dict: {a: b, c: "1 2 3", d: e, f: [g, h]}\n' + '...\n', conf) + self.check('---\n' + 'dict: {a: b, c: "1 2 3" , d: e, f: [g, h]}\n' + '...\n', conf, problem=(2, 24)) + self.check('---\n' + 'dict: {a: b , c: "1 2 3", d: e, f: [g , h]}\n' + '...\n', conf, problem1=(2, 12), problem2=(2, 42)) + self.check('---\n' + 'array: [\n' + ' elem,\n' + ' key: val,\n' + ']\n', conf) + self.check('---\n' + 'array: [\n' + ' elem ,\n' + ' key: val,\n' + ']\n', conf, problem=(3, 7)) + self.check('---\n' + 'map: {\n' + ' key1: val1,\n' + ' key2: val2,\n' + '}\n', conf) + self.check('---\n' + 'map: {\n' + ' key1: val1,\n' + ' key2: val2 ,\n' + '}\n', conf, problem=(4, 13)) + + def test_before_max(self): + conf = 'commas: {max-spaces-before: 3, max-spaces-after: -1}' + self.check('---\n' + 'array: [1 , 2, 3 , 4]\n' + '...\n', conf) + self.check('---\n' + 'array: [1 , 2, 3 , 4]\n' + '...\n', conf, problem=(2, 20)) + self.check('---\n' + 'array: [\n' + ' elem1 ,\n' + ' elem2 ,\n' + ' key: val,\n' + ']\n', conf, problem=(4, 11)) + + def test_after_enabled(self): + conf = 'commas: {max-spaces-before: -1, max-spaces-after: 1}' + self.check('---\n' + 'array: [1, 2, 3, 4]\n' + '...\n', conf) + self.check('---\n' + 'array: [1, 2, 3, 4]\n' + '...\n', conf, problem=(2, 15)) + self.check('---\n' + 'array: [1, 2, 3, 4]\n' + '...\n', conf, problem1=(2, 12), problem2=(2, 22)) + self.check('---\n' + 'dict: {a: b , c: "1 2 3", d: e, f: [g, h]}\n' + '...\n', conf) + self.check('---\n' + 'dict: {a: b , c: "1 2 3", d: e, f: [g, h]}\n' + '...\n', conf, problem=(2, 27)) + self.check('---\n' + 'dict: {a: b , c: "1 2 3", d: e, f: [g, h]}\n' + '...\n', conf, problem1=(2, 15), problem2=(2, 44)) + self.check('---\n' + 'array: [\n' + ' elem,\n' + ' key: val,\n' + ']\n', conf) + self.check('---\n' + 'array: [\n' + ' elem, key: val,\n' + ']\n', conf, problem=(3, 9)) + self.check('---\n' + 'map: {\n' + ' 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}' + self.check('---\n' + 'array: [1, 2, 3, 4]\n' + '...\n', conf) + self.check('---\n' + 'array: [1, 2, 3, 4]\n' + '...\n', conf, problem=(2, 21)) + self.check('---\n' + 'dict: {a: b , c: "1 2 3", d: e, f: [g, h]}\n' + '...\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}' + self.check('---\n' + 'dict: {a: b , c: "1 2 3", d: e , f: [g, h]}\n' + 'array: [\n' + ' elem ,\n' + ' key: val ,\n' + ']\n' + 'map: {\n' + ' key1: val1 ,\n' + ' key2: val2,\n' + '}\n' + '...\n', conf, + problem1=(2, 12), problem2=(2, 16), problem3=(2, 31), + problem4=(2, 36), problem5=(2, 50), problem6=(4, 8), + problem7=(5, 11), problem8=(8, 13)) diff --git a/yamllint/conf/default.yml b/yamllint/conf/default.yml index c4413fd..63c20c6 100644 --- a/yamllint/conf/default.yml +++ b/yamllint/conf/default.yml @@ -6,9 +6,9 @@ rules: colons: max-spaces-before: 0 max-spaces-after: 1 - #comma: - # max-spaces-before: 0 - # max-spaces-after: 1 + commas: + max-spaces-before: 0 + max-spaces-after: 1 #comment: # min-spaces-after: 1 # min-spaces-before: 2 diff --git a/yamllint/rules/__init__.py b/yamllint/rules/__init__.py index 6d818f2..28c5c8a 100644 --- a/yamllint/rules/__init__.py +++ b/yamllint/rules/__init__.py @@ -16,6 +16,7 @@ from yamllint.rules import ( colons, + commas, document_end, document_start, empty_lines, @@ -29,6 +30,7 @@ from yamllint.rules import ( _RULES = { colons.ID: colons, + commas.ID: commas, document_end.ID: document_end, document_start.ID: document_start, empty_lines.ID: empty_lines, diff --git a/yamllint/rules/commas.py b/yamllint/rules/commas.py new file mode 100644 index 0000000..ba1e4c4 --- /dev/null +++ b/yamllint/rules/commas.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016 Adrien Vergé +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import yaml + +from yamllint.rules.common import max_spaces_after, max_spaces_before + + +ID = 'commas' +TYPE = 'token' +CONF = {'max-spaces-before': int, + 'max-spaces-after': int} + + +def check(conf, token, prev, next): + if isinstance(token, yaml.FlowEntryToken): + problem = max_spaces_before(conf['max-spaces-before'], token, prev, + next, 'too many spaces before comma') + if problem is not None: + yield problem + + problem = max_spaces_after(conf['max-spaces-after'], token, prev, next, + 'too many spaces after comma') + if problem is not None: + yield problem