From 5c4c208b9821f6cf88038659dad480440c40a951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Wed, 13 Jan 2016 19:31:03 +0100 Subject: [PATCH] Rules: Add the 'braces' rule --- tests/rules/test_braces.py | 108 +++++++++++++++++++++++++++++++++++++ tests/rules/test_colons.py | 6 +-- yamllint/conf/default.yml | 6 +-- yamllint/rules/__init__.py | 2 + yamllint/rules/braces.py | 47 ++++++++++++++++ 5 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 tests/rules/test_braces.py create mode 100644 yamllint/rules/braces.py diff --git a/tests/rules/test_braces.py b/tests/rules/test_braces.py new file mode 100644 index 0000000..69f30af --- /dev/null +++ b/tests/rules/test_braces.py @@ -0,0 +1,108 @@ +# -*- 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 ColonTestCase(RuleTestCase): + rule_id = 'braces' + + def test_disabled(self): + conf = 'braces: disable' + self.check('---\n' + 'dict1: {}\n' + 'dict2: { }\n' + 'dict3: { a: 1, b}\n' + 'dict4: {a: 1, b, c: 3 }\n' + 'dict5: {a: 1, b, c: 3 }\n' + 'dict6: { a: 1, b, c: 3 }\n' + 'dict7: { a: 1, b, c: 3 }\n', conf) + + def test_min_spaces(self): + conf = 'braces: {max-spaces-inside: -1, min-spaces-inside: 0}' + self.check('---\n' + 'dict: {}\n', conf) + + conf = 'braces: {max-spaces-inside: -1, min-spaces-inside: 1}' + self.check('---\n' + 'dict: {}\n', conf, problem=(2, 8)) + self.check('---\n' + 'dict: { }\n', conf) + self.check('---\n' + 'dict: {a: 1, b}\n', conf, + problem1=(2, 8), problem2=(2, 15)) + self.check('---\n' + 'dict: { a: 1, b }\n', conf) + self.check('---\n' + 'dict: {\n' + ' a: 1,\n' + ' b\n' + '}\n', conf) + + conf = 'braces: {max-spaces-inside: -1, min-spaces-inside: 3}' + self.check('---\n' + 'dict: { a: 1, b }\n', conf, + problem1=(2, 9), problem2=(2, 17)) + self.check('---\n' + 'dict: { a: 1, b }\n', conf) + + def test_max_spaces(self): + conf = 'braces: {max-spaces-inside: 0, min-spaces-inside: -1}' + self.check('---\n' + 'dict: {}\n', conf) + self.check('---\n' + 'dict: { }\n', conf, problem=(2, 8)) + self.check('---\n' + 'dict: {a: 1, b}\n', conf) + self.check('---\n' + 'dict: { a: 1, b }\n', conf, + problem1=(2, 8), problem2=(2, 16)) + self.check('---\n' + 'dict: { a: 1, b }\n', conf, + problem1=(2, 10), problem2=(2, 20)) + self.check('---\n' + 'dict: {\n' + ' a: 1,\n' + ' b\n' + '}\n', conf) + + conf = 'braces: {max-spaces-inside: 3, min-spaces-inside: -1}' + self.check('---\n' + 'dict: { a: 1, b }\n', conf) + self.check('---\n' + 'dict: { a: 1, b }\n', conf, + problem1=(2, 11), problem2=(2, 23)) + + def test_min_and_max_spaces(self): + conf = 'braces: {max-spaces-inside: 0, min-spaces-inside: 0}' + self.check('---\n' + 'dict: {}\n', conf) + self.check('---\n' + 'dict: { }\n', conf, problem=(2, 8)) + self.check('---\n' + 'dict: { a: 1, b}\n', conf, problem=(2, 10)) + + conf = 'braces: {max-spaces-inside: 1, min-spaces-inside: 1}' + self.check('---\n' + 'dict: {a: 1, b, c: 3 }\n', conf, problem=(2, 8)) + + conf = 'braces: {max-spaces-inside: 2, min-spaces-inside: 0}' + self.check('---\n' + 'dict: {a: 1, b, c: 3 }\n', conf) + self.check('---\n' + 'dict: { a: 1, b, c: 3 }\n', conf) + self.check('---\n' + 'dict: { a: 1, b, c: 3 }\n', conf, problem=(2, 10)) diff --git a/tests/rules/test_colons.py b/tests/rules/test_colons.py index f64bdcc..9b45d32 100644 --- a/tests/rules/test_colons.py +++ b/tests/rules/test_colons.py @@ -38,7 +38,7 @@ class ColonTestCase(RuleTestCase): ' p:\n' ' - k3: >\n' ' val\n' - ' - o: { k1: v1 }\n' + ' - o: {k1: v1}\n' ' - p: kdjf\n' ' - q: val0\n' ' q2:\n' @@ -64,8 +64,8 @@ class ColonTestCase(RuleTestCase): ' val\n' ' - k3: >\n' ' val\n' - ' - o: { k1: v1 }\n' - ' - o: { k1: v1 }\n' + ' - o: {k1: v1}\n' + ' - o: {k1: v1}\n' ' q2:\n' ' - val1\n' '...\n', conf) diff --git a/yamllint/conf/default.yml b/yamllint/conf/default.yml index dd55af0..5b1a86d 100644 --- a/yamllint/conf/default.yml +++ b/yamllint/conf/default.yml @@ -3,12 +3,12 @@ rules: #block-sequence-indentation: # present: yes + braces: + min-spaces-inside: 0 + max-spaces-inside: 0 brackets: min-spaces-inside: 0 max-spaces-inside: 0 - #braces: - # min-spaces-inside: 0 - # max-spaces-inside: 0 colons: max-spaces-before: 0 max-spaces-after: 1 diff --git a/yamllint/rules/__init__.py b/yamllint/rules/__init__.py index 81bb0e7..854056b 100644 --- a/yamllint/rules/__init__.py +++ b/yamllint/rules/__init__.py @@ -15,6 +15,7 @@ # along with this program. If not, see . from yamllint.rules import ( + braces, brackets, colons, commas, @@ -30,6 +31,7 @@ from yamllint.rules import ( ) _RULES = { + braces.ID: braces, brackets.ID: brackets, colons.ID: colons, commas.ID: commas, diff --git a/yamllint/rules/braces.py b/yamllint/rules/braces.py new file mode 100644 index 0000000..f21278e --- /dev/null +++ b/yamllint/rules/braces.py @@ -0,0 +1,47 @@ +# -*- 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 spaces_after, spaces_before + + +ID = 'braces' +TYPE = 'token' +CONF = {'min-spaces-inside': int, + 'max-spaces-inside': int} + + +def check(conf, token, prev, next): + if isinstance(token, yaml.FlowMappingStartToken): + problem = spaces_after(token, prev, next, + min=conf['min-spaces-inside'], + max=conf['max-spaces-inside'], + min_desc='too few spaces inside braces', + max_desc='too many spaces inside braces') + if problem is not None: + yield problem + + elif (isinstance(token, yaml.FlowMappingEndToken) and + (prev is None or + not isinstance(prev, yaml.FlowMappingStartToken))): + problem = spaces_before(token, prev, next, + min=conf['min-spaces-inside'], + max=conf['max-spaces-inside'], + min_desc='too few spaces inside braces', + max_desc='too many spaces inside braces') + if problem is not None: + yield problem