From 41e53d951f2100b5622b1cc60d1764c043627393 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 9 Jan 2024 11:13:59 +0100 Subject: [PATCH] style: ruff format --- .ruff.toml | 3 + docs/conf.py | 4 +- tests/common.py | 8 +- tests/rules/test_anchors.py | 532 +-- tests/rules/test_braces.py | 528 ++- tests/rules/test_brackets.py | 509 ++- tests/rules/test_colons.py | 437 ++- tests/rules/test_commas.py | 483 +-- tests/rules/test_comments.py | 416 +-- tests/rules/test_comments_indentation.py | 212 +- tests/rules/test_common.py | 4 +- tests/rules/test_document_end.py | 106 +- tests/rules/test_document_start.py | 115 +- tests/rules/test_empty_lines.py | 85 +- tests/rules/test_empty_values.py | 560 ++-- tests/rules/test_float_values.py | 160 +- tests/rules/test_hyphens.py | 123 +- tests/rules/test_indentation.py | 3348 ++++++++++--------- tests/rules/test_key_duplicates.py | 454 +-- tests/rules/test_key_ordering.py | 160 +- tests/rules/test_line_length.py | 318 +- tests/rules/test_new_line_at_end_of_file.py | 20 +- tests/rules/test_new_lines.py | 22 +- tests/rules/test_octal_values.py | 48 +- tests/rules/test_quoted_strings.py | 2756 ++++++++------- tests/rules/test_trailing_spaces.py | 18 +- tests/rules/test_truthy.py | 217 +- tests/test_cli.py | 575 ++-- tests/test_config.py | 902 ++--- tests/test_linter.py | 11 +- tests/test_module.py | 33 +- tests/test_parser.py | 77 +- tests/test_spec_examples.py | 87 +- tests/test_syntax_errors.py | 110 +- tests/test_yamllint_directives.py | 833 ++--- yamllint/cli.py | 121 +- yamllint/config.py | 143 +- yamllint/linter.py | 52 +- yamllint/parser.py | 68 +- yamllint/rules/anchors.py | 86 +- yamllint/rules/braces.py | 120 +- yamllint/rules/brackets.py | 121 +- yamllint/rules/colons.py | 41 +- yamllint/rules/commas.py | 47 +- yamllint/rules/comments.py | 49 +- yamllint/rules/comments_indentation.py | 21 +- yamllint/rules/common.py | 67 +- yamllint/rules/document_end.py | 19 +- yamllint/rules/document_start.py | 24 +- yamllint/rules/empty_lines.py | 35 +- yamllint/rules/empty_values.py | 56 +- yamllint/rules/float_values.py | 8 +- yamllint/rules/hyphens.py | 10 +- yamllint/rules/indentation.py | 195 +- yamllint/rules/key_duplicates.py | 31 +- yamllint/rules/key_ordering.py | 24 +- yamllint/rules/line_length.py | 35 +- yamllint/rules/new_line_at_end_of_file.py | 7 +- yamllint/rules/new_lines.py | 9 +- yamllint/rules/octal_values.py | 33 +- yamllint/rules/quoted_strings.py | 165 +- yamllint/rules/trailing_spaces.py | 3 +- yamllint/rules/truthy.py | 50 +- 63 files changed, 8479 insertions(+), 7435 deletions(-) diff --git a/.ruff.toml b/.ruff.toml index aa08568d..37a5c733 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -3,3 +3,6 @@ extend-select = ["B", "I", "UP"] [lint.isort] known-third-party = ["tests"] + +[format] +quote-style = "single" diff --git a/docs/conf.py b/docs/conf.py index 98cc2c40..90f7d442 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -37,9 +37,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'yamllint', 'Linter for YAML files', ['Adrien Vergé'], 1) -] +man_pages = [('index', 'yamllint', 'Linter for YAML files', ['Adrien Vergé'], 1)] # -- Build with sphinx automodule without needing to install third-party libs diff --git a/tests/common.py b/tests/common.py index 1aef9e62..2de5cfba 100644 --- a/tests/common.py +++ b/tests/common.py @@ -31,8 +31,7 @@ def build_fake_config(self, conf): conf = {} else: conf = yaml.safe_load(conf) - conf = {'extends': 'default', - 'rules': conf} + conf = {'extends': 'default', 'rules': conf} return YamlLintConfig(yaml.safe_dump(conf)) def check(self, source, conf, **kwargs): @@ -46,8 +45,9 @@ def check(self, source, conf, **kwargs): rule_id = kwargs[key][2] else: rule_id = self.rule_id - expected_problems.append(linter.LintProblem( - kwargs[key][0], kwargs[key][1], rule=rule_id)) + expected_problems.append( + linter.LintProblem(kwargs[key][0], kwargs[key][1], rule=rule_id) + ) expected_problems.sort() real_problems = list(linter.run(source, self.build_fake_config(conf))) diff --git a/tests/rules/test_anchors.py b/tests/rules/test_anchors.py index 7d7cbb76..46ac07a7 100644 --- a/tests/rules/test_anchors.py +++ b/tests/rules/test_anchors.py @@ -21,261 +21,291 @@ class AnchorsTestCase(RuleTestCase): def test_disabled(self): conf = 'anchors: disable' - self.check('---\n' - '- &b true\n' - '- &i 42\n' - '- &s hello\n' - '- &f_m {k: v}\n' - '- &f_s [1, 2]\n' - '- *b\n' - '- *i\n' - '- *s\n' - '- *f_m\n' - '- *f_s\n' - '---\n' # redeclare anchors in a new document - '- &b true\n' - '- &i 42\n' - '- &s hello\n' - '- *b\n' - '- *i\n' - '- *s\n' - '---\n' - 'block mapping: &b_m\n' - ' key: value\n' - 'extended:\n' - ' <<: *b_m\n' - ' foo: bar\n' - '---\n' - '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' - '...\n', conf) - self.check('---\n' - '- &i 42\n' - '---\n' - '- &b true\n' - '- &b true\n' - '- &b true\n' - '- &s hello\n' - '- *b\n' - '- *i\n' # declared in a previous document - '- *f_m\n' # never declared - '- *f_m\n' - '- *f_m\n' - '- *f_s\n' # declared after - '- &f_s [1, 2]\n' - '---\n' - 'block mapping: &b_m\n' - ' key: value\n' - '---\n' - 'block mapping 1: &b_m_bis\n' - ' key: value\n' - 'block mapping 2: &b_m_bis\n' - ' key: value\n' - 'extended:\n' - ' <<: *b_m\n' - ' foo: bar\n' - '---\n' - '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' - '...\n', conf) + self.check( + '---\n' + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- &f_m {k: v}\n' + '- &f_s [1, 2]\n' + '- *b\n' + '- *i\n' + '- *s\n' + '- *f_m\n' + '- *f_s\n' + '---\n' # redeclare anchors in a new document + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- *b\n' + '- *i\n' + '- *s\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' + '...\n', + conf, + ) + self.check( + '---\n' + '- &i 42\n' + '---\n' + '- &b true\n' + '- &b true\n' + '- &b true\n' + '- &s hello\n' + '- *b\n' + '- *i\n' # declared in a previous document + '- *f_m\n' # never declared + '- *f_m\n' + '- *f_m\n' + '- *f_s\n' # declared after + '- &f_s [1, 2]\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + '---\n' + 'block mapping 1: &b_m_bis\n' + ' key: value\n' + 'block mapping 2: &b_m_bis\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' + '...\n', + conf, + ) def test_forbid_undeclared_aliases(self): - conf = ('anchors:\n' - ' forbid-undeclared-aliases: true\n' - ' forbid-duplicated-anchors: false\n' - ' forbid-unused-anchors: false\n') - self.check('---\n' - '- &b true\n' - '- &i 42\n' - '- &s hello\n' - '- &f_m {k: v}\n' - '- &f_s [1, 2]\n' - '- *b\n' - '- *i\n' - '- *s\n' - '- *f_m\n' - '- *f_s\n' - '---\n' # redeclare anchors in a new document - '- &b true\n' - '- &i 42\n' - '- &s hello\n' - '- *b\n' - '- *i\n' - '- *s\n' - '---\n' - 'block mapping: &b_m\n' - ' key: value\n' - 'extended:\n' - ' <<: *b_m\n' - ' foo: bar\n' - '---\n' - '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' - '...\n', conf) - self.check('---\n' - '- &i 42\n' - '---\n' - '- &b true\n' - '- &b true\n' - '- &b true\n' - '- &s hello\n' - '- *b\n' - '- *i\n' # declared in a previous document - '- *f_m\n' # never declared - '- *f_m\n' - '- *f_m\n' - '- *f_s\n' # declared after - '- &f_s [1, 2]\n' - '...\n' - '---\n' - 'block mapping: &b_m\n' - ' key: value\n' - '---\n' - 'block mapping 1: &b_m_bis\n' - ' key: value\n' - 'block mapping 2: &b_m_bis\n' - ' key: value\n' - 'extended:\n' - ' <<: *b_m\n' - ' foo: bar\n' - '---\n' - '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' - '...\n', conf, - problem1=(9, 3), - problem2=(10, 3), - problem3=(11, 3), - problem4=(12, 3), - problem5=(13, 3), - problem6=(25, 7), - problem7=(28, 37)) + conf = ( + 'anchors:\n' + ' forbid-undeclared-aliases: true\n' + ' forbid-duplicated-anchors: false\n' + ' forbid-unused-anchors: false\n' + ) + self.check( + '---\n' + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- &f_m {k: v}\n' + '- &f_s [1, 2]\n' + '- *b\n' + '- *i\n' + '- *s\n' + '- *f_m\n' + '- *f_s\n' + '---\n' # redeclare anchors in a new document + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- *b\n' + '- *i\n' + '- *s\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' + '...\n', + conf, + ) + self.check( + '---\n' + '- &i 42\n' + '---\n' + '- &b true\n' + '- &b true\n' + '- &b true\n' + '- &s hello\n' + '- *b\n' + '- *i\n' # declared in a previous document + '- *f_m\n' # never declared + '- *f_m\n' + '- *f_m\n' + '- *f_s\n' # declared after + '- &f_s [1, 2]\n' + '...\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + '---\n' + 'block mapping 1: &b_m_bis\n' + ' key: value\n' + 'block mapping 2: &b_m_bis\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' + '...\n', + conf, + problem1=(9, 3), + problem2=(10, 3), + problem3=(11, 3), + problem4=(12, 3), + problem5=(13, 3), + problem6=(25, 7), + problem7=(28, 37), + ) def test_forbid_duplicated_anchors(self): - conf = ('anchors:\n' - ' forbid-undeclared-aliases: false\n' - ' forbid-duplicated-anchors: true\n' - ' forbid-unused-anchors: false\n') - self.check('---\n' - '- &b true\n' - '- &i 42\n' - '- &s hello\n' - '- &f_m {k: v}\n' - '- &f_s [1, 2]\n' - '- *b\n' - '- *i\n' - '- *s\n' - '- *f_m\n' - '- *f_s\n' - '---\n' # redeclare anchors in a new document - '- &b true\n' - '- &i 42\n' - '- &s hello\n' - '- *b\n' - '- *i\n' - '- *s\n' - '---\n' - 'block mapping: &b_m\n' - ' key: value\n' - 'extended:\n' - ' <<: *b_m\n' - ' foo: bar\n' - '---\n' - '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' - '...\n', conf) - self.check('---\n' - '- &i 42\n' - '---\n' - '- &b true\n' - '- &b true\n' - '- &b true\n' - '- &s hello\n' - '- *b\n' - '- *i\n' # declared in a previous document - '- *f_m\n' # never declared - '- *f_m\n' - '- *f_m\n' - '- *f_s\n' # declared after - '- &f_s [1, 2]\n' - '...\n' - '---\n' - 'block mapping: &b_m\n' - ' key: value\n' - '---\n' - 'block mapping 1: &b_m_bis\n' - ' key: value\n' - 'block mapping 2: &b_m_bis\n' - ' key: value\n' - 'extended:\n' - ' <<: *b_m\n' - ' foo: bar\n' - '---\n' - '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' - '...\n', conf, - problem1=(5, 3), - problem2=(6, 3), - problem3=(22, 18), - problem4=(28, 20)) + conf = ( + 'anchors:\n' + ' forbid-undeclared-aliases: false\n' + ' forbid-duplicated-anchors: true\n' + ' forbid-unused-anchors: false\n' + ) + self.check( + '---\n' + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- &f_m {k: v}\n' + '- &f_s [1, 2]\n' + '- *b\n' + '- *i\n' + '- *s\n' + '- *f_m\n' + '- *f_s\n' + '---\n' # redeclare anchors in a new document + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- *b\n' + '- *i\n' + '- *s\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' + '...\n', + conf, + ) + self.check( + '---\n' + '- &i 42\n' + '---\n' + '- &b true\n' + '- &b true\n' + '- &b true\n' + '- &s hello\n' + '- *b\n' + '- *i\n' # declared in a previous document + '- *f_m\n' # never declared + '- *f_m\n' + '- *f_m\n' + '- *f_s\n' # declared after + '- &f_s [1, 2]\n' + '...\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + '---\n' + 'block mapping 1: &b_m_bis\n' + ' key: value\n' + 'block mapping 2: &b_m_bis\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' + '...\n', + conf, + problem1=(5, 3), + problem2=(6, 3), + problem3=(22, 18), + problem4=(28, 20), + ) def test_forbid_unused_anchors(self): - conf = ('anchors:\n' - ' forbid-undeclared-aliases: false\n' - ' forbid-duplicated-anchors: false\n' - ' forbid-unused-anchors: true\n') + conf = ( + 'anchors:\n' + ' forbid-undeclared-aliases: false\n' + ' forbid-duplicated-anchors: false\n' + ' forbid-unused-anchors: true\n' + ) - self.check('---\n' - '- &b true\n' - '- &i 42\n' - '- &s hello\n' - '- &f_m {k: v}\n' - '- &f_s [1, 2]\n' - '- *b\n' - '- *i\n' - '- *s\n' - '- *f_m\n' - '- *f_s\n' - '---\n' # redeclare anchors in a new document - '- &b true\n' - '- &i 42\n' - '- &s hello\n' - '- *b\n' - '- *i\n' - '- *s\n' - '---\n' - 'block mapping: &b_m\n' - ' key: value\n' - 'extended:\n' - ' <<: *b_m\n' - ' foo: bar\n' - '---\n' - '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' - '...\n', conf) - self.check('---\n' - '- &i 42\n' - '---\n' - '- &b true\n' - '- &b true\n' - '- &b true\n' - '- &s hello\n' - '- *b\n' - '- *i\n' # declared in a previous document - '- *f_m\n' # never declared - '- *f_m\n' - '- *f_m\n' - '- *f_s\n' # declared after - '- &f_s [1, 2]\n' - '...\n' - '---\n' - 'block mapping: &b_m\n' - ' key: value\n' - '---\n' - 'block mapping 1: &b_m_bis\n' - ' key: value\n' - 'block mapping 2: &b_m_bis\n' - ' key: value\n' - 'extended:\n' - ' <<: *b_m\n' - ' foo: bar\n' - '---\n' - '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' - '...\n', conf, - problem1=(2, 3), - problem2=(7, 3), - problem3=(14, 3), - problem4=(17, 16), - problem5=(22, 18)) + self.check( + '---\n' + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- &f_m {k: v}\n' + '- &f_s [1, 2]\n' + '- *b\n' + '- *i\n' + '- *s\n' + '- *f_m\n' + '- *f_s\n' + '---\n' # redeclare anchors in a new document + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- *b\n' + '- *i\n' + '- *s\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' + '...\n', + conf, + ) + self.check( + '---\n' + '- &i 42\n' + '---\n' + '- &b true\n' + '- &b true\n' + '- &b true\n' + '- &s hello\n' + '- *b\n' + '- *i\n' # declared in a previous document + '- *f_m\n' # never declared + '- *f_m\n' + '- *f_m\n' + '- *f_s\n' # declared after + '- &f_s [1, 2]\n' + '...\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + '---\n' + 'block mapping 1: &b_m_bis\n' + ' key: value\n' + 'block mapping 2: &b_m_bis\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' + '...\n', + conf, + problem1=(2, 3), + problem2=(7, 3), + problem3=(14, 3), + problem4=(17, 16), + problem5=(22, 18), + ) diff --git a/tests/rules/test_braces.py b/tests/rules/test_braces.py index 03636a93..0ac28040 100644 --- a/tests/rules/test_braces.py +++ b/tests/rules/test_braces.py @@ -21,320 +21,274 @@ class ColonTestCase(RuleTestCase): 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) + 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_forbid(self): - conf = ('braces:\n' - ' forbid: false\n') - self.check('---\n' - 'dict: {}\n', conf) - self.check('---\n' - 'dict: {a}\n', conf) - self.check('---\n' - 'dict: {a: 1}\n', conf) - self.check('---\n' - 'dict: {\n' - ' a: 1\n' - '}\n', conf) + conf = 'braces:\n' ' forbid: false\n' + self.check('---\n' 'dict: {}\n', conf) + self.check('---\n' 'dict: {a}\n', conf) + self.check('---\n' 'dict: {a: 1}\n', conf) + self.check('---\n' 'dict: {\n' ' a: 1\n' '}\n', conf) - conf = ('braces:\n' - ' forbid: true\n') - self.check('---\n' - 'dict:\n' - ' a: 1\n', conf) - self.check('---\n' - 'dict: {}\n', conf, problem=(2, 8)) - self.check('---\n' - 'dict: {a}\n', conf, problem=(2, 8)) - self.check('---\n' - 'dict: {a: 1}\n', conf, problem=(2, 8)) - self.check('---\n' - 'dict: {\n' - ' a: 1\n' - '}\n', conf, problem=(2, 8)) + conf = 'braces:\n' ' forbid: true\n' + self.check('---\n' 'dict:\n' ' a: 1\n', conf) + self.check('---\n' 'dict: {}\n', conf, problem=(2, 8)) + self.check('---\n' 'dict: {a}\n', conf, problem=(2, 8)) + self.check('---\n' 'dict: {a: 1}\n', conf, problem=(2, 8)) + self.check('---\n' 'dict: {\n' ' a: 1\n' '}\n', conf, problem=(2, 8)) - conf = ('braces:\n' - ' forbid: non-empty\n') - self.check('---\n' - 'dict:\n' - ' a: 1\n', conf) - self.check('---\n' - 'dict: {}\n', conf) - self.check('---\n' - 'dict: {\n' - '}\n', conf) - self.check('---\n' - 'dict: {\n' - '# commented: value\n' - '# another: value2\n' - '}\n', conf) - self.check('---\n' - 'dict: {a}\n', conf, problem=(2, 8)) - self.check('---\n' - 'dict: {a: 1}\n', conf, problem=(2, 8)) - self.check('---\n' - 'dict: {\n' - ' a: 1\n' - '}\n', conf, problem=(2, 8)) + conf = 'braces:\n' ' forbid: non-empty\n' + self.check('---\n' 'dict:\n' ' a: 1\n', conf) + self.check('---\n' 'dict: {}\n', conf) + self.check('---\n' 'dict: {\n' '}\n', conf) + self.check( + '---\n' 'dict: {\n' '# commented: value\n' '# another: value2\n' '}\n', conf + ) + self.check('---\n' 'dict: {a}\n', conf, problem=(2, 8)) + self.check('---\n' 'dict: {a: 1}\n', conf, problem=(2, 8)) + self.check('---\n' 'dict: {\n' ' a: 1\n' '}\n', conf, problem=(2, 8)) def test_min_spaces(self): - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: 0\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'dict: {}\n', conf) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: 0\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'dict: {}\n', conf) - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - 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:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + 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:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: 3\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'dict: { a: 1, b }\n', conf, - problem1=(2, 9), problem2=(2, 17)) - self.check('---\n' - 'dict: { a: 1, b }\n', conf) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: 3\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + 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:\n' - ' max-spaces-inside: 0\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - 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:\n' + ' max-spaces-inside: 0\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + 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:\n' - ' max-spaces-inside: 3\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'dict: { a: 1, b }\n', conf) - self.check('---\n' - 'dict: { a: 1, b }\n', conf, - problem1=(2, 11), problem2=(2, 23)) + conf = ( + 'braces:\n' + ' max-spaces-inside: 3\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + 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:\n' - ' max-spaces-inside: 0\n' - ' min-spaces-inside: 0\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - 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:\n' + ' max-spaces-inside: 0\n' + ' min-spaces-inside: 0\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + 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:\n' - ' max-spaces-inside: 1\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'dict: {a: 1, b, c: 3 }\n', conf, problem=(2, 8)) + conf = ( + 'braces:\n' + ' max-spaces-inside: 1\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'dict: {a: 1, b, c: 3 }\n', conf, problem=(2, 8)) - conf = ('braces:\n' - ' max-spaces-inside: 2\n' - ' min-spaces-inside: 0\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - 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)) + conf = ( + 'braces:\n' + ' max-spaces-inside: 2\n' + ' min-spaces-inside: 0\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + 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)) def test_min_spaces_empty(self): - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 0\n' - ' min-spaces-inside-empty: 0\n') - self.check('---\n' - 'array: {}\n', conf) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 0\n' + ' min-spaces-inside-empty: 0\n' + ) + self.check('---\n' 'array: {}\n', conf) - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: {}\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: { }\n', conf) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: {}\n', conf, problem=(2, 9)) + self.check('---\n' 'array: { }\n', conf) - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: 3\n') - self.check('---\n' - 'array: {}\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: { }\n', conf) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: 3\n' + ) + self.check('---\n' 'array: {}\n', conf, problem=(2, 9)) + self.check('---\n' 'array: { }\n', conf) def test_max_spaces_empty(self): - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 0\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: {}\n', conf) - self.check('---\n' - 'array: { }\n', conf, problem=(2, 9)) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 0\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: {}\n', conf) + self.check('---\n' 'array: { }\n', conf, problem=(2, 9)) - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: {}\n', conf) - self.check('---\n' - 'array: { }\n', conf) - self.check('---\n' - 'array: { }\n', conf, problem=(2, 10)) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: {}\n', conf) + self.check('---\n' 'array: { }\n', conf) + self.check('---\n' 'array: { }\n', conf, problem=(2, 10)) - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 3\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: {}\n', conf) - self.check('---\n' - 'array: { }\n', conf) - self.check('---\n' - 'array: { }\n', conf, problem=(2, 12)) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 3\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: {}\n', conf) + self.check('---\n' 'array: { }\n', conf) + self.check('---\n' 'array: { }\n', conf, problem=(2, 12)) def test_min_and_max_spaces_empty(self): - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 2\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: {}\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: { }\n', conf) - self.check('---\n' - 'array: { }\n', conf) - self.check('---\n' - 'array: { }\n', conf, problem=(2, 11)) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 2\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: {}\n', conf, problem=(2, 9)) + self.check('---\n' 'array: { }\n', conf) + self.check('---\n' 'array: { }\n', conf) + self.check('---\n' 'array: { }\n', conf, problem=(2, 11)) def test_mixed_empty_nonempty(self): - conf = ('braces:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: 0\n' - ' min-spaces-inside-empty: 0\n') - self.check('---\n' - 'array: { a: 1, b }\n', conf) - self.check('---\n' - 'array: {a: 1, b}\n', conf, - problem1=(2, 9), problem2=(2, 16)) - self.check('---\n' - 'array: {}\n', conf) - self.check('---\n' - 'array: { }\n', conf, - problem1=(2, 9)) + conf = ( + 'braces:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: 0\n' + ' min-spaces-inside-empty: 0\n' + ) + self.check('---\n' 'array: { a: 1, b }\n', conf) + self.check( + '---\n' 'array: {a: 1, b}\n', conf, problem1=(2, 9), problem2=(2, 16) + ) + self.check('---\n' 'array: {}\n', conf) + self.check('---\n' 'array: { }\n', conf, problem1=(2, 9)) - conf = ('braces:\n' - ' max-spaces-inside: 0\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 1\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: { a: 1, b }\n', conf, - problem1=(2, 9), problem2=(2, 17)) - self.check('---\n' - 'array: {a: 1, b}\n', conf) - self.check('---\n' - 'array: {}\n', conf, - problem1=(2, 9)) - self.check('---\n' - 'array: { }\n', conf) + conf = ( + 'braces:\n' + ' max-spaces-inside: 0\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 1\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check( + '---\n' 'array: { a: 1, b }\n', conf, problem1=(2, 9), problem2=(2, 17) + ) + self.check('---\n' 'array: {a: 1, b}\n', conf) + self.check('---\n' 'array: {}\n', conf, problem1=(2, 9)) + self.check('---\n' 'array: { }\n', conf) - conf = ('braces:\n' - ' max-spaces-inside: 2\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: 1\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: { a: 1, b }\n', conf) - self.check('---\n' - 'array: {a: 1, b }\n', conf, - problem1=(2, 9), problem2=(2, 18)) - self.check('---\n' - 'array: {}\n', conf, - problem1=(2, 9)) - self.check('---\n' - 'array: { }\n', conf) - self.check('---\n' - 'array: { }\n', conf, - problem1=(2, 11)) + conf = ( + 'braces:\n' + ' max-spaces-inside: 2\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: 1\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: { a: 1, b }\n', conf) + self.check( + '---\n' 'array: {a: 1, b }\n', conf, problem1=(2, 9), problem2=(2, 18) + ) + self.check('---\n' 'array: {}\n', conf, problem1=(2, 9)) + self.check('---\n' 'array: { }\n', conf) + self.check('---\n' 'array: { }\n', conf, problem1=(2, 11)) - conf = ('braces:\n' - ' max-spaces-inside: 1\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: 1\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: { a: 1, b }\n', conf) - self.check('---\n' - 'array: {a: 1, b}\n', conf, - problem1=(2, 9), problem2=(2, 16)) - self.check('---\n' - 'array: {}\n', conf, - problem1=(2, 9)) - self.check('---\n' - 'array: { }\n', conf) + conf = ( + 'braces:\n' + ' max-spaces-inside: 1\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: 1\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: { a: 1, b }\n', conf) + self.check( + '---\n' 'array: {a: 1, b}\n', conf, problem1=(2, 9), problem2=(2, 16) + ) + self.check('---\n' 'array: {}\n', conf, problem1=(2, 9)) + self.check('---\n' 'array: { }\n', conf) diff --git a/tests/rules/test_brackets.py b/tests/rules/test_brackets.py index e17566b8..da3989c1 100644 --- a/tests/rules/test_brackets.py +++ b/tests/rules/test_brackets.py @@ -21,317 +21,258 @@ class ColonTestCase(RuleTestCase): def test_disabled(self): conf = 'brackets: disable' - self.check('---\n' - 'array1: []\n' - 'array2: [ ]\n' - 'array3: [ a, b]\n' - 'array4: [a, b, c ]\n' - 'array5: [a, b, c ]\n' - 'array6: [ a, b, c ]\n' - 'array7: [ a, b, c ]\n', conf) + self.check( + '---\n' + 'array1: []\n' + 'array2: [ ]\n' + 'array3: [ a, b]\n' + 'array4: [a, b, c ]\n' + 'array5: [a, b, c ]\n' + 'array6: [ a, b, c ]\n' + 'array7: [ a, b, c ]\n', + conf, + ) def test_forbid(self): - conf = ('brackets:\n' - ' forbid: false\n') - self.check('---\n' - 'array: []\n', conf) - self.check('---\n' - 'array: [a, b]\n', conf) - self.check('---\n' - 'array: [\n' - ' a,\n' - ' b\n' - ']\n', conf) + conf = 'brackets:\n' ' forbid: false\n' + self.check('---\n' 'array: []\n', conf) + self.check('---\n' 'array: [a, b]\n', conf) + self.check('---\n' 'array: [\n' ' a,\n' ' b\n' ']\n', conf) - conf = ('brackets:\n' - ' forbid: true\n') - self.check('---\n' - 'array:\n' - ' - a\n' - ' - b\n', conf) - self.check('---\n' - 'array: []\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [a, b]\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [\n' - ' a,\n' - ' b\n' - ']\n', conf, problem=(2, 9)) + conf = 'brackets:\n' ' forbid: true\n' + self.check('---\n' 'array:\n' ' - a\n' ' - b\n', conf) + self.check('---\n' 'array: []\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [a, b]\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [\n' ' a,\n' ' b\n' ']\n', conf, problem=(2, 9)) - conf = ('brackets:\n' - ' forbid: non-empty\n') - self.check('---\n' - 'array:\n' - ' - a\n' - ' - b\n', conf) - self.check('---\n' - 'array: []\n', conf) - self.check('---\n' - 'array: [\n\n' - ']\n', conf) - self.check('---\n' - 'array: [\n' - '# a comment\n' - ']\n', conf) - self.check('---\n' - 'array: [a, b]\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [\n' - ' a,\n' - ' b\n' - ']\n', conf, problem=(2, 9)) + conf = 'brackets:\n' ' forbid: non-empty\n' + self.check('---\n' 'array:\n' ' - a\n' ' - b\n', conf) + self.check('---\n' 'array: []\n', conf) + self.check('---\n' 'array: [\n\n' ']\n', conf) + self.check('---\n' 'array: [\n' '# a comment\n' ']\n', conf) + self.check('---\n' 'array: [a, b]\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [\n' ' a,\n' ' b\n' ']\n', conf, problem=(2, 9)) def test_min_spaces(self): - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: 0\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: []\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: 0\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: []\n', conf) - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: []\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [ ]\n', conf) - self.check('---\n' - 'array: [a, b]\n', conf, problem1=(2, 9), problem2=(2, 13)) - self.check('---\n' - 'array: [ a, b ]\n', conf) - self.check('---\n' - 'array: [\n' - ' a,\n' - ' b\n' - ']\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: []\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [ ]\n', conf) + self.check('---\n' 'array: [a, b]\n', conf, problem1=(2, 9), problem2=(2, 13)) + self.check('---\n' 'array: [ a, b ]\n', conf) + self.check('---\n' 'array: [\n' ' a,\n' ' b\n' ']\n', conf) - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: 3\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: [ a, b ]\n', conf, - problem1=(2, 10), problem2=(2, 15)) - self.check('---\n' - 'array: [ a, b ]\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: 3\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check( + '---\n' 'array: [ a, b ]\n', conf, problem1=(2, 10), problem2=(2, 15) + ) + self.check('---\n' 'array: [ a, b ]\n', conf) def test_max_spaces(self): - conf = ('brackets:\n' - ' max-spaces-inside: 0\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: []\n', conf) - self.check('---\n' - 'array: [ ]\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [a, b]\n', conf) - self.check('---\n' - 'array: [ a, b ]\n', conf, - problem1=(2, 9), problem2=(2, 14)) - self.check('---\n' - 'array: [ a, b ]\n', conf, - problem1=(2, 11), problem2=(2, 18)) - self.check('---\n' - 'array: [\n' - ' a,\n' - ' b\n' - ']\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: 0\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: []\n', conf) + self.check('---\n' 'array: [ ]\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [a, b]\n', conf) + self.check('---\n' 'array: [ a, b ]\n', conf, problem1=(2, 9), problem2=(2, 14)) + self.check( + '---\n' 'array: [ a, b ]\n', conf, problem1=(2, 11), problem2=(2, 18) + ) + self.check('---\n' 'array: [\n' ' a,\n' ' b\n' ']\n', conf) - conf = ('brackets:\n' - ' max-spaces-inside: 3\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: [ a, b ]\n', conf) - self.check('---\n' - 'array: [ a, b ]\n', conf, - problem1=(2, 12), problem2=(2, 21)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: 3\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: [ a, b ]\n', conf) + self.check( + '---\n' 'array: [ a, b ]\n', conf, problem1=(2, 12), problem2=(2, 21) + ) def test_min_and_max_spaces(self): - conf = ('brackets:\n' - ' max-spaces-inside: 0\n' - ' min-spaces-inside: 0\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: []\n', conf) - self.check('---\n' - 'array: [ ]\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [ a, b]\n', conf, problem=(2, 11)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: 0\n' + ' min-spaces-inside: 0\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: []\n', conf) + self.check('---\n' 'array: [ ]\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [ a, b]\n', conf, problem=(2, 11)) - conf = ('brackets:\n' - ' max-spaces-inside: 1\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: [a, b, c ]\n', conf, problem=(2, 9)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: 1\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: [a, b, c ]\n', conf, problem=(2, 9)) - conf = ('brackets:\n' - ' max-spaces-inside: 2\n' - ' min-spaces-inside: 0\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: [a, b, c ]\n', conf) - self.check('---\n' - 'array: [ a, b, c ]\n', conf) - self.check('---\n' - 'array: [ a, b, c ]\n', conf, problem=(2, 11)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: 2\n' + ' min-spaces-inside: 0\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: [a, b, c ]\n', conf) + self.check('---\n' 'array: [ a, b, c ]\n', conf) + self.check('---\n' 'array: [ a, b, c ]\n', conf, problem=(2, 11)) def test_min_spaces_empty(self): - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 0\n' - ' min-spaces-inside-empty: 0\n') - self.check('---\n' - 'array: []\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 0\n' + ' min-spaces-inside-empty: 0\n' + ) + self.check('---\n' 'array: []\n', conf) - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: []\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [ ]\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: []\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [ ]\n', conf) - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: -1\n' - ' min-spaces-inside-empty: 3\n') - self.check('---\n' - 'array: []\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [ ]\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: -1\n' + ' min-spaces-inside-empty: 3\n' + ) + self.check('---\n' 'array: []\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [ ]\n', conf) def test_max_spaces_empty(self): - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 0\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: []\n', conf) - self.check('---\n' - 'array: [ ]\n', conf, problem=(2, 9)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 0\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: []\n', conf) + self.check('---\n' 'array: [ ]\n', conf, problem=(2, 9)) - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 1\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: []\n', conf) - self.check('---\n' - 'array: [ ]\n', conf) - self.check('---\n' - 'array: [ ]\n', conf, problem=(2, 10)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 1\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: []\n', conf) + self.check('---\n' 'array: [ ]\n', conf) + self.check('---\n' 'array: [ ]\n', conf, problem=(2, 10)) - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 3\n' - ' min-spaces-inside-empty: -1\n') - self.check('---\n' - 'array: []\n', conf) - self.check('---\n' - 'array: [ ]\n', conf) - self.check('---\n' - 'array: [ ]\n', conf, problem=(2, 12)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 3\n' + ' min-spaces-inside-empty: -1\n' + ) + self.check('---\n' 'array: []\n', conf) + self.check('---\n' 'array: [ ]\n', conf) + self.check('---\n' 'array: [ ]\n', conf, problem=(2, 12)) def test_min_and_max_spaces_empty(self): - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 2\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: []\n', conf, problem=(2, 9)) - self.check('---\n' - 'array: [ ]\n', conf) - self.check('---\n' - 'array: [ ]\n', conf) - self.check('---\n' - 'array: [ ]\n', conf, problem=(2, 11)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 2\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: []\n', conf, problem=(2, 9)) + self.check('---\n' 'array: [ ]\n', conf) + self.check('---\n' 'array: [ ]\n', conf) + self.check('---\n' 'array: [ ]\n', conf, problem=(2, 11)) def test_mixed_empty_nonempty(self): - conf = ('brackets:\n' - ' max-spaces-inside: -1\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: 0\n' - ' min-spaces-inside-empty: 0\n') - self.check('---\n' - 'array: [ a, b ]\n', conf) - self.check('---\n' - 'array: [a, b]\n', conf, - problem1=(2, 9), problem2=(2, 13)) - self.check('---\n' - 'array: []\n', conf) - self.check('---\n' - 'array: [ ]\n', conf, - problem1=(2, 9)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: -1\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: 0\n' + ' min-spaces-inside-empty: 0\n' + ) + self.check('---\n' 'array: [ a, b ]\n', conf) + self.check('---\n' 'array: [a, b]\n', conf, problem1=(2, 9), problem2=(2, 13)) + self.check('---\n' 'array: []\n', conf) + self.check('---\n' 'array: [ ]\n', conf, problem1=(2, 9)) - conf = ('brackets:\n' - ' max-spaces-inside: 0\n' - ' min-spaces-inside: -1\n' - ' max-spaces-inside-empty: 1\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: [ a, b ]\n', conf, - problem1=(2, 9), problem2=(2, 14)) - self.check('---\n' - 'array: [a, b]\n', conf) - self.check('---\n' - 'array: []\n', conf, - problem1=(2, 9)) - self.check('---\n' - 'array: [ ]\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: 0\n' + ' min-spaces-inside: -1\n' + ' max-spaces-inside-empty: 1\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: [ a, b ]\n', conf, problem1=(2, 9), problem2=(2, 14)) + self.check('---\n' 'array: [a, b]\n', conf) + self.check('---\n' 'array: []\n', conf, problem1=(2, 9)) + self.check('---\n' 'array: [ ]\n', conf) - conf = ('brackets:\n' - ' max-spaces-inside: 2\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: 1\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: [ a, b ]\n', conf) - self.check('---\n' - 'array: [a, b ]\n', conf, - problem1=(2, 9), problem2=(2, 15)) - self.check('---\n' - 'array: []\n', conf, - problem1=(2, 9)) - self.check('---\n' - 'array: [ ]\n', conf) - self.check('---\n' - 'array: [ ]\n', conf, - problem1=(2, 11)) + conf = ( + 'brackets:\n' + ' max-spaces-inside: 2\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: 1\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: [ a, b ]\n', conf) + self.check( + '---\n' 'array: [a, b ]\n', conf, problem1=(2, 9), problem2=(2, 15) + ) + self.check('---\n' 'array: []\n', conf, problem1=(2, 9)) + self.check('---\n' 'array: [ ]\n', conf) + self.check('---\n' 'array: [ ]\n', conf, problem1=(2, 11)) - conf = ('brackets:\n' - ' max-spaces-inside: 1\n' - ' min-spaces-inside: 1\n' - ' max-spaces-inside-empty: 1\n' - ' min-spaces-inside-empty: 1\n') - self.check('---\n' - 'array: [ a, b ]\n', conf) - self.check('---\n' - 'array: [a, b]\n', conf, - problem1=(2, 9), problem2=(2, 13)) - self.check('---\n' - 'array: []\n', conf, - problem1=(2, 9)) - self.check('---\n' - 'array: [ ]\n', conf) + conf = ( + 'brackets:\n' + ' max-spaces-inside: 1\n' + ' min-spaces-inside: 1\n' + ' max-spaces-inside-empty: 1\n' + ' min-spaces-inside-empty: 1\n' + ) + self.check('---\n' 'array: [ a, b ]\n', conf) + self.check('---\n' 'array: [a, b]\n', conf, problem1=(2, 9), problem2=(2, 13)) + self.check('---\n' 'array: []\n', conf, problem1=(2, 9)) + self.check('---\n' 'array: [ ]\n', conf) diff --git a/tests/rules/test_colons.py b/tests/rules/test_colons.py index 5467c8be..4a6148f0 100644 --- a/tests/rules/test_colons.py +++ b/tests/rules/test_colons.py @@ -21,254 +21,253 @@ class ColonTestCase(RuleTestCase): def test_disabled(self): conf = 'colons: disable' - self.check('---\n' - 'object:\n' - ' k1 : v1\n' - 'obj2:\n' - ' k2 :\n' - ' - 8\n' - ' k3:\n' - ' val\n' - ' property : value\n' - ' prop2 : val2\n' - ' propriété : [valeur]\n' - ' o:\n' - ' k1: [v1, v2]\n' - ' p:\n' - ' - k3: >\n' - ' val\n' - ' - o: {k1: v1}\n' - ' - p: kdjf\n' - ' - q: val0\n' - ' - q2:\n' - ' - val1\n' - '...\n', conf) - self.check('---\n' - 'object:\n' - ' k1: v1\n' - 'obj2:\n' - ' k2:\n' - ' - 8\n' - ' k3:\n' - ' val\n' - ' property: value\n' - ' prop2: val2\n' - ' propriété: [valeur]\n' - ' o:\n' - ' k1: [v1, v2]\n', conf) - self.check('---\n' - 'obj:\n' - ' p:\n' - ' - k1: >\n' - ' val\n' - ' - k3: >\n' - ' val\n' - ' - o: {k1: v1}\n' - ' - o: {k1: v1}\n' - ' - q2:\n' - ' - val1\n' - '...\n', conf) - self.check('---\n' - 'a: {b: {c: d, e : f}}\n', conf) + self.check( + '---\n' + 'object:\n' + ' k1 : v1\n' + 'obj2:\n' + ' k2 :\n' + ' - 8\n' + ' k3:\n' + ' val\n' + ' property : value\n' + ' prop2 : val2\n' + ' propriété : [valeur]\n' + ' o:\n' + ' k1: [v1, v2]\n' + ' p:\n' + ' - k3: >\n' + ' val\n' + ' - o: {k1: v1}\n' + ' - p: kdjf\n' + ' - q: val0\n' + ' - q2:\n' + ' - val1\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'object:\n' + ' k1: v1\n' + 'obj2:\n' + ' k2:\n' + ' - 8\n' + ' k3:\n' + ' val\n' + ' property: value\n' + ' prop2: val2\n' + ' propriété: [valeur]\n' + ' o:\n' + ' k1: [v1, v2]\n', + conf, + ) + self.check( + '---\n' + 'obj:\n' + ' p:\n' + ' - k1: >\n' + ' val\n' + ' - k3: >\n' + ' val\n' + ' - o: {k1: v1}\n' + ' - o: {k1: v1}\n' + ' - q2:\n' + ' - val1\n' + '...\n', + conf, + ) + self.check('---\n' 'a: {b: {c: d, e : f}}\n', conf) def test_before_enabled(self): conf = 'colons: {max-spaces-before: 0, max-spaces-after: -1}' - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - '...\n', conf) - self.check('---\n' - 'object:\n' - ' k1 :\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - '...\n', conf, problem=(3, 5)) - self.check('---\n' - 'lib :\n' - ' - var\n' - '...\n', conf, problem=(2, 4)) - self.check('---\n' - '- lib :\n' - ' - var\n' - '...\n', conf, problem=(2, 6)) - self.check('---\n' - 'a: {b: {c : d, e : f}}\n', conf, - problem1=(2, 10), problem2=(2, 17)) + self.check( + '---\n' 'object:\n' ' k1:\n' ' - a\n' ' - b\n' ' k2: v2\n' '...\n', + conf, + ) + self.check( + '---\n' 'object:\n' ' k1 :\n' ' - a\n' ' - b\n' ' k2: v2\n' '...\n', + conf, + problem=(3, 5), + ) + self.check('---\n' 'lib :\n' ' - var\n' '...\n', conf, problem=(2, 4)) + self.check('---\n' '- lib :\n' ' - var\n' '...\n', conf, problem=(2, 6)) + self.check( + '---\n' 'a: {b: {c : d, e : f}}\n', conf, problem1=(2, 10), problem2=(2, 17) + ) def test_before_max(self): conf = 'colons: {max-spaces-before: 3, max-spaces-after: -1}' - self.check('---\n' - 'object :\n' - ' k1 :\n' - ' - a\n' - ' - b\n' - ' k2 : v2\n' - '...\n', conf) - self.check('---\n' - 'object :\n' - ' k1 :\n' - ' - a\n' - ' - b\n' - ' k2 : v2\n' - '...\n', conf, problem=(3, 8)) + self.check( + '---\n' + 'object :\n' + ' k1 :\n' + ' - a\n' + ' - b\n' + ' k2 : v2\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'object :\n' + ' k1 :\n' + ' - a\n' + ' - b\n' + ' k2 : v2\n' + '...\n', + conf, + problem=(3, 8), + ) def test_before_with_explicit_block_mappings(self): conf = 'colons: {max-spaces-before: 0, max-spaces-after: 1}' - self.check('---\n' - 'object:\n' - ' ? key\n' - ' : value\n' - '...\n', conf) - self.check('---\n' - 'object :\n' - ' ? key\n' - ' : value\n' - '...\n', conf, problem=(2, 7)) - self.check('---\n' - '? >\n' - ' multi-line\n' - ' key\n' - ': >\n' - ' multi-line\n' - ' value\n' - '...\n', conf) - self.check('---\n' - '- ? >\n' - ' multi-line\n' - ' key\n' - ' : >\n' - ' multi-line\n' - ' value\n' - '...\n', conf) - self.check('---\n' - '- ? >\n' - ' multi-line\n' - ' key\n' - ' : >\n' - ' multi-line\n' - ' value\n' - '...\n', conf, problem=(5, 5)) + self.check('---\n' 'object:\n' ' ? key\n' ' : value\n' '...\n', conf) + self.check( + '---\n' 'object :\n' ' ? key\n' ' : value\n' '...\n', conf, problem=(2, 7) + ) + self.check( + '---\n' + '? >\n' + ' multi-line\n' + ' key\n' + ': >\n' + ' multi-line\n' + ' value\n' + '...\n', + conf, + ) + self.check( + '---\n' + '- ? >\n' + ' multi-line\n' + ' key\n' + ' : >\n' + ' multi-line\n' + ' value\n' + '...\n', + conf, + ) + self.check( + '---\n' + '- ? >\n' + ' multi-line\n' + ' key\n' + ' : >\n' + ' multi-line\n' + ' value\n' + '...\n', + conf, + problem=(5, 5), + ) def test_after_enabled(self): conf = 'colons: {max-spaces-before: -1, max-spaces-after: 1}' - self.check('---\n' - 'key: value\n', conf) - self.check('---\n' - 'key: value\n', conf, problem=(2, 6)) - self.check('---\n' - 'object:\n' - ' k1: [a, b]\n' - ' k2: string\n', conf, problem=(3, 7)) - self.check('---\n' - 'object:\n' - ' k1: [a, b]\n' - ' k2: string\n', conf, problem=(4, 7)) - self.check('---\n' - 'object:\n' - ' other: {key: value}\n' - '...\n', conf, problem=(3, 16)) - self.check('---\n' - 'a: {b: {c: d, e : f}}\n', conf, - problem1=(2, 12), problem2=(2, 20)) + self.check('---\n' 'key: value\n', conf) + self.check('---\n' 'key: value\n', conf, problem=(2, 6)) + self.check( + '---\n' 'object:\n' ' k1: [a, b]\n' ' k2: string\n', conf, problem=(3, 7) + ) + self.check( + '---\n' 'object:\n' ' k1: [a, b]\n' ' k2: string\n', conf, problem=(4, 7) + ) + self.check( + '---\n' 'object:\n' ' other: {key: value}\n' '...\n', + conf, + problem=(3, 16), + ) + self.check( + '---\n' 'a: {b: {c: d, e : f}}\n', + conf, + problem1=(2, 12), + problem2=(2, 20), + ) def test_after_enabled_question_mark(self): conf = 'colons: {max-spaces-before: -1, max-spaces-after: 1}' - self.check('---\n' - '? key\n' - ': value\n', conf) - self.check('---\n' - '? key\n' - ': value\n', conf, problem=(2, 3)) - self.check('---\n' - '? key\n' - ': value\n', conf, problem1=(2, 3), problem2=(3, 3)) - self.check('---\n' - '- ? key\n' - ' : value\n', conf, problem1=(2, 5), problem2=(3, 5)) + self.check('---\n' '? key\n' ': value\n', conf) + self.check('---\n' '? key\n' ': value\n', conf, problem=(2, 3)) + self.check( + '---\n' '? key\n' ': value\n', conf, problem1=(2, 3), problem2=(3, 3) + ) + self.check( + '---\n' '- ? key\n' ' : value\n', conf, problem1=(2, 5), problem2=(3, 5) + ) def test_after_max(self): conf = 'colons: {max-spaces-before: -1, max-spaces-after: 3}' - self.check('---\n' - 'object:\n' - ' k1: [a, b]\n', conf) - self.check('---\n' - 'object:\n' - ' k1: [a, b]\n', conf, problem=(3, 9)) - self.check('---\n' - 'object:\n' - ' k2: string\n', conf) - self.check('---\n' - 'object:\n' - ' k2: string\n', conf, problem=(3, 9)) - self.check('---\n' - 'object:\n' - ' other: {key: value}\n' - '...\n', conf) - self.check('---\n' - 'object:\n' - ' other: {key: value}\n' - '...\n', conf, problem=(3, 18)) + self.check('---\n' 'object:\n' ' k1: [a, b]\n', conf) + self.check('---\n' 'object:\n' ' k1: [a, b]\n', conf, problem=(3, 9)) + self.check('---\n' 'object:\n' ' k2: string\n', conf) + self.check('---\n' 'object:\n' ' k2: string\n', conf, problem=(3, 9)) + self.check('---\n' 'object:\n' ' other: {key: value}\n' '...\n', conf) + self.check( + '---\n' 'object:\n' ' other: {key: value}\n' '...\n', + conf, + problem=(3, 18), + ) def test_after_with_explicit_block_mappings(self): conf = 'colons: {max-spaces-before: -1, max-spaces-after: 1}' - self.check('---\n' - 'object:\n' - ' ? key\n' - ' : value\n' - '...\n', conf) - self.check('---\n' - 'object:\n' - ' ? key\n' - ' : value\n' - '...\n', conf, problem=(4, 5)) + self.check('---\n' 'object:\n' ' ? key\n' ' : value\n' '...\n', conf) + self.check( + '---\n' 'object:\n' ' ? key\n' ' : value\n' '...\n', conf, problem=(4, 5) + ) def test_after_do_not_confound_with_trailing_space(self): - conf = ('colons: {max-spaces-before: 1, max-spaces-after: 1}\n' - 'trailing-spaces: disable\n') - self.check('---\n' - 'trailing: \n' - ' - spaces\n', conf) + conf = ( + 'colons: {max-spaces-before: 1, max-spaces-after: 1}\n' + 'trailing-spaces: disable\n' + ) + self.check('---\n' 'trailing: \n' ' - spaces\n', conf) def test_both_before_and_after(self): conf = 'colons: {max-spaces-before: 0, max-spaces-after: 1}' - self.check('---\n' - 'obj:\n' - ' string: text\n' - ' k:\n' - ' - 8\n' - ' k3:\n' - ' val\n' - ' property: [value]\n', conf) - self.check('---\n' - 'object:\n' - ' k1 : v1\n', conf, problem1=(3, 5), problem2=(3, 8)) - self.check('---\n' - 'obj:\n' - ' string: text\n' - ' k :\n' - ' - 8\n' - ' k3:\n' - ' val\n' - ' property: {a: 1, b: 2, c : 3}\n', conf, - problem1=(3, 11), problem2=(4, 4), - problem3=(8, 23), problem4=(8, 28)) + self.check( + '---\n' + 'obj:\n' + ' string: text\n' + ' k:\n' + ' - 8\n' + ' k3:\n' + ' val\n' + ' property: [value]\n', + conf, + ) + self.check( + '---\n' 'object:\n' ' k1 : v1\n', conf, problem1=(3, 5), problem2=(3, 8) + ) + self.check( + '---\n' + 'obj:\n' + ' string: text\n' + ' k :\n' + ' - 8\n' + ' k3:\n' + ' val\n' + ' property: {a: 1, b: 2, c : 3}\n', + conf, + problem1=(3, 11), + problem2=(4, 4), + problem3=(8, 23), + problem4=(8, 28), + ) # Although accepted by PyYAML, `{*x: 4}` is not valid YAML: it should be # noted `{*x : 4}`. The reason is that a colon can be part of an anchor # name. See commit message for more details. def test_with_alias_as_key(self): conf = 'colons: {max-spaces-before: 0, max-spaces-after: 1}' - self.check('---\n' - '- anchor: &a key\n' - '- *a: 42\n' - '- {*a: 42}\n' - '- *a : 42\n' - '- {*a : 42}\n' - '- *a : 42\n' - '- {*a : 42}\n', - conf, - problem1=(7, 6), problem2=(8, 7)) + self.check( + '---\n' + '- anchor: &a key\n' + '- *a: 42\n' + '- {*a: 42}\n' + '- *a : 42\n' + '- {*a : 42}\n' + '- *a : 42\n' + '- {*a : 42}\n', + conf, + problem1=(7, 6), + problem2=(8, 7), + ) diff --git a/tests/rules/test_commas.py b/tests/rules/test_commas.py index 0d0abd8b..07c8158e 100644 --- a/tests/rules/test_commas.py +++ b/tests/rules/test_commas.py @@ -21,244 +21,275 @@ class CommaTestCase(RuleTestCase): 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) - 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) + 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, + ) + 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_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) - 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)) + 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) + 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_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' + ) + 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)) + 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) - 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)) + 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) + 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_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)) + 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) - 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)) + 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) + 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_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) - 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)) + 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) + 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:\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' - ' 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)) - conf = ('commas:\n' - ' max-spaces-before: 0\n' - ' min-spaces-after: 1\n' - ' max-spaces-after: 1\n' - 'indentation: disable\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, 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)) + 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' + ' 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), + ) + conf = ( + 'commas:\n' + ' max-spaces-before: 0\n' + ' min-spaces-after: 1\n' + ' max-spaces-after: 1\n' + 'indentation: disable\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, 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/tests/rules/test_comments.py b/tests/rules/test_comments.py index 1f5a20c1..5265c044 100644 --- a/tests/rules/test_comments.py +++ b/tests/rules/test_comments.py @@ -20,217 +20,255 @@ class CommentsTestCase(RuleTestCase): rule_id = 'comments' def test_disabled(self): - conf = ('comments: disable\n' - 'comments-indentation: disable\n') - self.check('---\n' - '#comment\n' - '\n' - 'test: # description\n' - ' - foo # bar\n' - ' - hello #world\n' - '\n' - '# comment 2\n' - '#comment 3\n' - ' #comment 3 bis\n' - ' # comment 3 ter\n' - '\n' - '################################\n' - '## comment 4\n' - '##comment 5\n' - '\n' - 'string: "Une longue phrase." # this is French\n', conf) + conf = 'comments: disable\n' 'comments-indentation: disable\n' + self.check( + '---\n' + '#comment\n' + '\n' + 'test: # description\n' + ' - foo # bar\n' + ' - hello #world\n' + '\n' + '# comment 2\n' + '#comment 3\n' + ' #comment 3 bis\n' + ' # comment 3 ter\n' + '\n' + '################################\n' + '## comment 4\n' + '##comment 5\n' + '\n' + 'string: "Une longue phrase." # this is French\n', + conf, + ) def test_starting_space(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' min-spaces-from-content: -1\n' - 'comments-indentation: disable\n') - self.check('---\n' - '# comment\n' - '\n' - 'test: # description\n' - ' - foo # bar\n' - ' - hello # world\n' - '\n' - '# comment 2\n' - '# comment 3\n' - ' # comment 3 bis\n' - ' # comment 3 ter\n' - '\n' - '################################\n' - '## comment 4\n' - '## comment 5\n', conf) - self.check('---\n' - '#comment\n' - '\n' - 'test: # description\n' - ' - foo # bar\n' - ' - hello #world\n' - '\n' - '# comment 2\n' - '#comment 3\n' - ' #comment 3 bis\n' - ' # comment 3 ter\n' - '\n' - '################################\n' - '## comment 4\n' - '##comment 5\n', conf, - problem1=(2, 2), problem2=(6, 13), - problem3=(9, 2), problem4=(10, 4), - problem5=(15, 3)) + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: -1\n' + 'comments-indentation: disable\n' + ) + self.check( + '---\n' + '# comment\n' + '\n' + 'test: # description\n' + ' - foo # bar\n' + ' - hello # world\n' + '\n' + '# comment 2\n' + '# comment 3\n' + ' # comment 3 bis\n' + ' # comment 3 ter\n' + '\n' + '################################\n' + '## comment 4\n' + '## comment 5\n', + conf, + ) + self.check( + '---\n' + '#comment\n' + '\n' + 'test: # description\n' + ' - foo # bar\n' + ' - hello #world\n' + '\n' + '# comment 2\n' + '#comment 3\n' + ' #comment 3 bis\n' + ' # comment 3 ter\n' + '\n' + '################################\n' + '## comment 4\n' + '##comment 5\n', + conf, + problem1=(2, 2), + problem2=(6, 13), + problem3=(9, 2), + problem4=(10, 4), + problem5=(15, 3), + ) def test_shebang(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' ignore-shebangs: false\n' - 'comments-indentation: disable\n' - 'document-start: disable\n') - self.check('#!/bin/env my-interpreter\n', - conf, problem1=(1, 2)) - self.check('# comment\n' - '#!/bin/env my-interpreter\n', conf, - problem1=(2, 2)) - self.check('#!/bin/env my-interpreter\n' - '---\n' - '#comment\n' - '#!/bin/env my-interpreter\n' - '', conf, - problem1=(1, 2), problem2=(3, 2), problem3=(4, 2)) - self.check('#! is a valid shebang too\n', - conf, problem1=(1, 2)) - self.check('key: #!/not/a/shebang\n', - conf, problem1=(1, 8)) + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' ignore-shebangs: false\n' + 'comments-indentation: disable\n' + 'document-start: disable\n' + ) + self.check('#!/bin/env my-interpreter\n', conf, problem1=(1, 2)) + self.check('# comment\n' '#!/bin/env my-interpreter\n', conf, problem1=(2, 2)) + self.check( + '#!/bin/env my-interpreter\n' + '---\n' + '#comment\n' + '#!/bin/env my-interpreter\n' + '', + conf, + problem1=(1, 2), + problem2=(3, 2), + problem3=(4, 2), + ) + self.check('#! is a valid shebang too\n', conf, problem1=(1, 2)) + self.check('key: #!/not/a/shebang\n', conf, problem1=(1, 8)) def test_ignore_shebang(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' ignore-shebangs: true\n' - 'comments-indentation: disable\n' - 'document-start: disable\n') + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' ignore-shebangs: true\n' + 'comments-indentation: disable\n' + 'document-start: disable\n' + ) self.check('#!/bin/env my-interpreter\n', conf) - self.check('# comment\n' - '#!/bin/env my-interpreter\n', conf, - problem1=(2, 2)) - self.check('#!/bin/env my-interpreter\n' - '---\n' - '#comment\n' - '#!/bin/env my-interpreter\n', conf, - problem2=(3, 2), problem3=(4, 2)) + self.check('# comment\n' '#!/bin/env my-interpreter\n', conf, problem1=(2, 2)) + self.check( + '#!/bin/env my-interpreter\n' + '---\n' + '#comment\n' + '#!/bin/env my-interpreter\n', + conf, + problem2=(3, 2), + problem3=(4, 2), + ) self.check('#! is a valid shebang too\n', conf) - self.check('key: #!/not/a/shebang\n', - conf, problem1=(1, 8)) + self.check('key: #!/not/a/shebang\n', conf, problem1=(1, 8)) def test_spaces_from_content(self): - conf = ('comments:\n' - ' require-starting-space: false\n' - ' min-spaces-from-content: 2\n') - self.check('---\n' - '# comment\n' - '\n' - 'test: # description\n' - ' - foo # bar\n' - ' - hello #world\n' - '\n' - 'string: "Une longue phrase." # this is French\n', conf) - self.check('---\n' - '# comment\n' - '\n' - 'test: # description\n' - ' - foo # bar\n' - ' - hello #world\n' - '\n' - 'string: "Une longue phrase." # this is French\n', conf, - problem1=(4, 7), problem2=(6, 11), problem3=(8, 30)) + conf = ( + 'comments:\n' + ' require-starting-space: false\n' + ' min-spaces-from-content: 2\n' + ) + self.check( + '---\n' + '# comment\n' + '\n' + 'test: # description\n' + ' - foo # bar\n' + ' - hello #world\n' + '\n' + 'string: "Une longue phrase." # this is French\n', + conf, + ) + self.check( + '---\n' + '# comment\n' + '\n' + 'test: # description\n' + ' - foo # bar\n' + ' - hello #world\n' + '\n' + 'string: "Une longue phrase." # this is French\n', + conf, + problem1=(4, 7), + problem2=(6, 11), + problem3=(8, 30), + ) def test_both(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' min-spaces-from-content: 2\n' - 'comments-indentation: disable\n') - self.check('---\n' - '#comment\n' - '\n' - 'test: # description\n' - ' - foo # bar\n' - ' - hello #world\n' - '\n' - '# comment 2\n' - '#comment 3\n' - ' #comment 3 bis\n' - ' # comment 3 ter\n' - '\n' - '################################\n' - '## comment 4\n' - '##comment 5\n' - '\n' - 'string: "Une longue phrase." # this is French\n', conf, - problem1=(2, 2), - problem2=(4, 7), - problem3=(6, 11), problem4=(6, 12), - problem5=(9, 2), - problem6=(10, 4), - problem7=(15, 3), - problem8=(17, 30)) + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + 'comments-indentation: disable\n' + ) + self.check( + '---\n' + '#comment\n' + '\n' + 'test: # description\n' + ' - foo # bar\n' + ' - hello #world\n' + '\n' + '# comment 2\n' + '#comment 3\n' + ' #comment 3 bis\n' + ' # comment 3 ter\n' + '\n' + '################################\n' + '## comment 4\n' + '##comment 5\n' + '\n' + 'string: "Une longue phrase." # this is French\n', + conf, + problem1=(2, 2), + problem2=(4, 7), + problem3=(6, 11), + problem4=(6, 12), + problem5=(9, 2), + problem6=(10, 4), + problem7=(15, 3), + problem8=(17, 30), + ) def test_empty_comment(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' min-spaces-from-content: 2\n') - self.check('---\n' - '# This is paragraph 1.\n' - '#\n' - '# This is paragraph 2.\n', conf) - self.check('---\n' - 'inline: comment #\n' - 'foo: bar\n', conf) + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + ) + self.check( + '---\n' '# This is paragraph 1.\n' '#\n' '# This is paragraph 2.\n', conf + ) + self.check('---\n' 'inline: comment #\n' 'foo: bar\n', conf) def test_empty_comment_crlf_dos_newlines(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' min-spaces-from-content: 2\n' - 'new-lines:\n' - ' type: dos\n') - self.check('---\r\n' - '# This is paragraph 1.\r\n' - '#\r\n' - '# This is paragraph 2.\r\n', conf) + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + 'new-lines:\n' + ' type: dos\n' + ) + self.check( + '---\r\n' '# This is paragraph 1.\r\n' '#\r\n' '# This is paragraph 2.\r\n', + conf, + ) def test_empty_comment_crlf_disabled_newlines(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' min-spaces-from-content: 2\n' - 'new-lines: disable\n') - self.check('---\r\n' - '# This is paragraph 1.\r\n' - '#\r\n' - '# This is paragraph 2.\r\n', conf) + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + 'new-lines: disable\n' + ) + self.check( + '---\r\n' '# This is paragraph 1.\r\n' '#\r\n' '# This is paragraph 2.\r\n', + conf, + ) def test_first_line(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' min-spaces-from-content: 2\n') + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + ) self.check('# comment\n', conf) def test_last_line(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' min-spaces-from-content: 2\n' - 'new-line-at-end-of-file: disable\n') - self.check('# comment with no newline char:\n' - '#', conf) + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + 'new-line-at-end-of-file: disable\n' + ) + self.check('# comment with no newline char:\n' '#', conf) def test_multi_line_scalar(self): - conf = ('comments:\n' - ' require-starting-space: true\n' - ' min-spaces-from-content: 2\n' - 'trailing-spaces: disable\n') - self.check('---\n' - 'string: >\n' - ' this is plain text\n' - '\n' - '# comment\n', conf) - self.check('---\n' - '- string: >\n' - ' this is plain text\n' - ' \n' - ' # comment\n', conf) + conf = ( + 'comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + 'trailing-spaces: disable\n' + ) + self.check( + '---\n' 'string: >\n' ' this is plain text\n' '\n' '# comment\n', conf + ) + self.check( + '---\n' '- string: >\n' ' this is plain text\n' ' \n' ' # comment\n', + conf, + ) diff --git a/tests/rules/test_comments_indentation.py b/tests/rules/test_comments_indentation.py index 0aa5aac6..4b34fe1d 100644 --- a/tests/rules/test_comments_indentation.py +++ b/tests/rules/test_comments_indentation.py @@ -21,105 +21,100 @@ class CommentsIndentationTestCase(RuleTestCase): def test_disable(self): conf = 'comments-indentation: disable' - self.check('---\n' - ' # line 1\n' - '# line 2\n' - ' # line 3\n' - ' # line 4\n' - '\n' - 'obj:\n' - ' # these\n' - ' # are\n' - ' # [good]\n' - '# bad\n' - ' # comments\n' - ' a: b\n' - '\n' - 'obj1:\n' - ' a: 1\n' - ' # comments\n' - '\n' - 'obj2:\n' - ' b: 2\n' - '\n' - '# empty\n' - '#\n' - '# comment\n' - '...\n', conf) + self.check( + '---\n' + ' # line 1\n' + '# line 2\n' + ' # line 3\n' + ' # line 4\n' + '\n' + 'obj:\n' + ' # these\n' + ' # are\n' + ' # [good]\n' + '# bad\n' + ' # comments\n' + ' a: b\n' + '\n' + 'obj1:\n' + ' a: 1\n' + ' # comments\n' + '\n' + 'obj2:\n' + ' b: 2\n' + '\n' + '# empty\n' + '#\n' + '# comment\n' + '...\n', + conf, + ) def test_enabled(self): conf = 'comments-indentation: enable' - self.check('---\n' - '# line 1\n' - '# line 2\n', conf) - self.check('---\n' - ' # line 1\n' - '# line 2\n', conf, problem=(2, 2)) - self.check('---\n' - ' # line 1\n' - ' # line 2\n', conf, problem1=(2, 3)) - self.check('---\n' - 'obj:\n' - ' # normal\n' - ' a: b\n', conf) - self.check('---\n' - 'obj:\n' - ' # bad\n' - ' a: b\n', conf, problem=(3, 2)) - self.check('---\n' - 'obj:\n' - '# bad\n' - ' a: b\n', conf, problem=(3, 1)) - self.check('---\n' - 'obj:\n' - ' # bad\n' - ' a: b\n', conf, problem=(3, 4)) - self.check('---\n' - 'obj:\n' - ' # these\n' - ' # are\n' - ' # [good]\n' - '# bad\n' - ' # comments\n' - ' a: b\n', conf, - problem1=(3, 2), problem2=(4, 4), - problem3=(6, 1), problem4=(7, 7)) - self.check('---\n' - 'obj1:\n' - ' a: 1\n' - ' # the following line is disabled\n' - ' # b: 2\n', conf) - self.check('---\n' - 'obj1:\n' - ' a: 1\n' - ' # b: 2\n' - '\n' - 'obj2:\n' - ' b: 2\n', conf) - self.check('---\n' - 'obj1:\n' - ' a: 1\n' - ' # b: 2\n' - '# this object is useless\n' - 'obj2: "no"\n', conf) - self.check('---\n' - 'obj1:\n' - ' a: 1\n' - '# this object is useless\n' - ' # b: 2\n' - 'obj2: "no"\n', conf, problem=(5, 3)) - self.check('---\n' - 'obj1:\n' - ' a: 1\n' - ' # comments\n' - ' b: 2\n', conf) - self.check('---\n' - 'my list for today:\n' - ' - todo 1\n' - ' - todo 2\n' - ' # commented for now\n' - ' # - todo 3\n' - '...\n', conf) + self.check('---\n' '# line 1\n' '# line 2\n', conf) + self.check('---\n' ' # line 1\n' '# line 2\n', conf, problem=(2, 2)) + self.check('---\n' ' # line 1\n' ' # line 2\n', conf, problem1=(2, 3)) + self.check('---\n' 'obj:\n' ' # normal\n' ' a: b\n', conf) + self.check('---\n' 'obj:\n' ' # bad\n' ' a: b\n', conf, problem=(3, 2)) + self.check('---\n' 'obj:\n' '# bad\n' ' a: b\n', conf, problem=(3, 1)) + self.check('---\n' 'obj:\n' ' # bad\n' ' a: b\n', conf, problem=(3, 4)) + self.check( + '---\n' + 'obj:\n' + ' # these\n' + ' # are\n' + ' # [good]\n' + '# bad\n' + ' # comments\n' + ' a: b\n', + conf, + problem1=(3, 2), + problem2=(4, 4), + problem3=(6, 1), + problem4=(7, 7), + ) + self.check( + '---\n' + 'obj1:\n' + ' a: 1\n' + ' # the following line is disabled\n' + ' # b: 2\n', + conf, + ) + self.check( + '---\n' 'obj1:\n' ' a: 1\n' ' # b: 2\n' '\n' 'obj2:\n' ' b: 2\n', conf + ) + self.check( + '---\n' + 'obj1:\n' + ' a: 1\n' + ' # b: 2\n' + '# this object is useless\n' + 'obj2: "no"\n', + conf, + ) + self.check( + '---\n' + 'obj1:\n' + ' a: 1\n' + '# this object is useless\n' + ' # b: 2\n' + 'obj2: "no"\n', + conf, + problem=(5, 3), + ) + self.check('---\n' 'obj1:\n' ' a: 1\n' ' # comments\n' ' b: 2\n', conf) + self.check( + '---\n' + 'my list for today:\n' + ' - todo 1\n' + ' - todo 2\n' + ' # commented for now\n' + ' # - todo 3\n' + '...\n', + conf, + ) def test_first_line(self): conf = 'comments-indentation: enable' @@ -127,30 +122,17 @@ def test_first_line(self): self.check(' # comment\n', conf, problem=(1, 3)) def test_no_newline_at_end(self): - conf = ('comments-indentation: enable\n' - 'new-line-at-end-of-file: disable\n') + conf = 'comments-indentation: enable\n' 'new-line-at-end-of-file: disable\n' self.check('# comment', conf) self.check(' # comment', conf, problem=(1, 3)) def test_empty_comment(self): conf = 'comments-indentation: enable' - self.check('---\n' - '# hey\n' - '# normal\n' - '#\n', conf) - self.check('---\n' - '# hey\n' - '# normal\n' - ' #\n', conf, problem=(4, 2)) + self.check('---\n' '# hey\n' '# normal\n' '#\n', conf) + self.check('---\n' '# hey\n' '# normal\n' ' #\n', conf, problem=(4, 2)) def test_inline_comment(self): conf = 'comments-indentation: enable' - self.check('---\n' - '- a # inline\n' - '# ok\n', conf) - self.check('---\n' - '- a # inline\n' - ' # not ok\n', conf, problem=(3, 2)) - self.check('---\n' - ' # not ok\n' - '- a # inline\n', conf, problem=(2, 2)) + self.check('---\n' '- a # inline\n' '# ok\n', conf) + self.check('---\n' '- a # inline\n' ' # not ok\n', conf, problem=(3, 2)) + self.check('---\n' ' # not ok\n' '- a # inline\n', conf, problem=(2, 2)) diff --git a/tests/rules/test_common.py b/tests/rules/test_common.py index 196b419c..6eb3a026 100644 --- a/tests/rules/test_common.py +++ b/tests/rules/test_common.py @@ -22,9 +22,7 @@ class CommonTestCase(unittest.TestCase): def test_get_line_indent(self): - tokens = list(yaml.scan('a: 1\n' - 'b:\n' - ' - c: [2, 3, {d: 4}]\n')) + tokens = list(yaml.scan('a: 1\n' 'b:\n' ' - c: [2, 3, {d: 4}]\n')) self.assertEqual(tokens[3].value, 'a') self.assertEqual(tokens[5].value, '1') diff --git a/tests/rules/test_document_end.py b/tests/rules/test_document_end.py index 8340c6f8..8397bc8b 100644 --- a/tests/rules/test_document_end.py +++ b/tests/rules/test_document_end.py @@ -21,72 +21,66 @@ class DocumentEndTestCase(RuleTestCase): def test_disabled(self): conf = 'document-end: disable' - self.check('---\n' - 'with:\n' - ' document: end\n' - '...\n', conf) - self.check('---\n' - 'without:\n' - ' document: end\n', conf) + self.check('---\n' 'with:\n' ' document: end\n' '...\n', conf) + self.check('---\n' 'without:\n' ' document: end\n', conf) def test_required(self): conf = 'document-end: {present: true}' self.check('', conf) self.check('\n', conf) - self.check('---\n' - 'with:\n' - ' document: end\n' - '...\n', conf) - self.check('---\n' - 'without:\n' - ' document: end\n', conf, problem=(3, 1)) + self.check('---\n' 'with:\n' ' document: end\n' '...\n', conf) + self.check('---\n' 'without:\n' ' document: end\n', conf, problem=(3, 1)) def test_forbidden(self): conf = 'document-end: {present: false}' - self.check('---\n' - 'with:\n' - ' document: end\n' - '...\n', conf, problem=(4, 1)) - self.check('---\n' - 'without:\n' - ' document: end\n', conf) + self.check('---\n' 'with:\n' ' document: end\n' '...\n', conf, problem=(4, 1)) + self.check('---\n' 'without:\n' ' document: end\n', conf) def test_multiple_documents(self): - conf = ('document-end: {present: true}\n' - 'document-start: disable\n') - self.check('---\n' - 'first: document\n' - '...\n' - '---\n' - 'second: document\n' - '...\n' - '---\n' - 'third: document\n' - '...\n', conf) - self.check('---\n' - 'first: document\n' - '...\n' - '---\n' - 'second: document\n' - '---\n' - 'third: document\n' - '...\n', conf, problem=(6, 1)) + conf = 'document-end: {present: true}\n' 'document-start: disable\n' + self.check( + '---\n' + 'first: document\n' + '...\n' + '---\n' + 'second: document\n' + '...\n' + '---\n' + 'third: document\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'first: document\n' + '...\n' + '---\n' + 'second: document\n' + '---\n' + 'third: document\n' + '...\n', + conf, + problem=(6, 1), + ) def test_directives(self): conf = 'document-end: {present: true}' - self.check('%YAML 1.2\n' - '---\n' - 'document: end\n' - '...\n', conf) - self.check('%YAML 1.2\n' - '%TAG ! tag:clarkevans.com,2002:\n' - '---\n' - 'document: end\n' - '...\n', conf) - self.check('---\n' - 'first: document\n' - '...\n' - '%YAML 1.2\n' - '---\n' - 'second: document\n' - '...\n', conf) + self.check('%YAML 1.2\n' '---\n' 'document: end\n' '...\n', conf) + self.check( + '%YAML 1.2\n' + '%TAG ! tag:clarkevans.com,2002:\n' + '---\n' + 'document: end\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'first: document\n' + '...\n' + '%YAML 1.2\n' + '---\n' + 'second: document\n' + '...\n', + conf, + ) diff --git a/tests/rules/test_document_start.py b/tests/rules/test_document_start.py index ee2e9d38..40231459 100644 --- a/tests/rules/test_document_start.py +++ b/tests/rules/test_document_start.py @@ -23,81 +23,70 @@ def test_disabled(self): conf = 'document-start: disable' self.check('', conf) self.check('key: val\n', conf) - self.check('---\n' - 'key: val\n', conf) + self.check('---\n' 'key: val\n', conf) def test_required(self): - conf = ('document-start: {present: true}\n' - 'empty-lines: disable\n') + conf = 'document-start: {present: true}\n' 'empty-lines: disable\n' self.check('', conf) self.check('\n', conf) self.check('key: val\n', conf, problem=(1, 1)) - self.check('\n' - '\n' - 'key: val\n', conf, problem=(3, 1)) - self.check('---\n' - 'key: val\n', conf) - self.check('\n' - '\n' - '---\n' - 'key: val\n', conf) + self.check('\n' '\n' 'key: val\n', conf, problem=(3, 1)) + self.check('---\n' 'key: val\n', conf) + self.check('\n' '\n' '---\n' 'key: val\n', conf) def test_forbidden(self): - conf = ('document-start: {present: false}\n' - 'empty-lines: disable\n') + conf = 'document-start: {present: false}\n' 'empty-lines: disable\n' self.check('', conf) self.check('key: val\n', conf) - self.check('\n' - '\n' - 'key: val\n', conf) - self.check('---\n' - 'key: val\n', conf, problem=(1, 1)) - self.check('\n' - '\n' - '---\n' - 'key: val\n', conf, problem=(3, 1)) - self.check('first: document\n' - '---\n' - 'key: val\n', conf, problem=(2, 1)) + self.check('\n' '\n' 'key: val\n', conf) + self.check('---\n' 'key: val\n', conf, problem=(1, 1)) + self.check('\n' '\n' '---\n' 'key: val\n', conf, problem=(3, 1)) + self.check('first: document\n' '---\n' 'key: val\n', conf, problem=(2, 1)) def test_multiple_documents(self): conf = 'document-start: {present: true}' - self.check('---\n' - 'first: document\n' - '...\n' - '---\n' - 'second: document\n' - '...\n' - '---\n' - 'third: document\n', conf) - self.check('---\n' - 'first: document\n' - '---\n' - 'second: document\n' - '---\n' - 'third: document\n', conf) - self.check('---\n' - 'first: document\n' - '...\n' - 'second: document\n' - '---\n' - 'third: document\n', conf, problem=(4, 1, 'syntax')) + self.check( + '---\n' + 'first: document\n' + '...\n' + '---\n' + 'second: document\n' + '...\n' + '---\n' + 'third: document\n', + conf, + ) + self.check( + '---\n' + 'first: document\n' + '---\n' + 'second: document\n' + '---\n' + 'third: document\n', + conf, + ) + self.check( + '---\n' + 'first: document\n' + '...\n' + 'second: document\n' + '---\n' + 'third: document\n', + conf, + problem=(4, 1, 'syntax'), + ) def test_directives(self): conf = 'document-start: {present: true}' - self.check('%YAML 1.2\n' - '---\n' - 'doc: ument\n' - '...\n', conf) - self.check('%YAML 1.2\n' - '%TAG ! tag:clarkevans.com,2002:\n' - '---\n' - 'doc: ument\n' - '...\n', conf) - self.check('---\n' - 'doc: 1\n' - '...\n' - '%YAML 1.2\n' - '---\n' - 'doc: 2\n' - '...\n', conf) + self.check('%YAML 1.2\n' '---\n' 'doc: ument\n' '...\n', conf) + self.check( + '%YAML 1.2\n' + '%TAG ! tag:clarkevans.com,2002:\n' + '---\n' + 'doc: ument\n' + '...\n', + conf, + ) + self.check( + '---\n' 'doc: 1\n' '...\n' '%YAML 1.2\n' '---\n' 'doc: 2\n' '...\n', conf + ) diff --git a/tests/rules/test_empty_lines.py b/tests/rules/test_empty_lines.py index fbecbcd9..3f1e1048 100644 --- a/tests/rules/test_empty_lines.py +++ b/tests/rules/test_empty_lines.py @@ -20,9 +20,11 @@ class EmptyLinesTestCase(RuleTestCase): rule_id = 'empty-lines' def test_disabled(self): - conf = ('empty-lines: disable\n' - 'new-line-at-end-of-file: disable\n' - 'document-start: disable\n') + conf = ( + 'empty-lines: disable\n' + 'new-line-at-end-of-file: disable\n' + 'document-start: disable\n' + ) self.check('', conf) self.check('\n', conf) self.check('\n\n', conf) @@ -32,15 +34,19 @@ def test_disabled(self): self.check('\n\n\nsome text\n\n\n', conf) def test_empty_document(self): - conf = ('empty-lines: {max: 0, max-start: 0, max-end: 0}\n' - 'new-line-at-end-of-file: disable\n' - 'document-start: disable\n') + conf = ( + 'empty-lines: {max: 0, max-start: 0, max-end: 0}\n' + 'new-line-at-end-of-file: disable\n' + 'document-start: disable\n' + ) self.check('', conf) self.check('\n', conf) def test_0_empty_lines(self): - conf = ('empty-lines: {max: 0, max-start: 0, max-end: 0}\n' - 'new-line-at-end-of-file: disable\n') + conf = ( + 'empty-lines: {max: 0, max-start: 0, max-end: 0}\n' + 'new-line-at-end-of-file: disable\n' + ) self.check('---\n', conf) self.check('---\ntext\n\ntext', conf, problem=(3, 1)) self.check('---\ntext\n\ntext\n', conf, problem=(3, 1)) @@ -48,51 +54,60 @@ def test_0_empty_lines(self): def test_10_empty_lines(self): conf = 'empty-lines: {max: 10, max-start: 0, max-end: 0}' self.check('---\nintro\n\n\n\n\n\n\n\n\n\n\nconclusion\n', conf) - self.check('---\nintro\n\n\n\n\n\n\n\n\n\n\n\nconclusion\n', conf, - problem=(13, 1)) + self.check( + '---\nintro\n\n\n\n\n\n\n\n\n\n\n\nconclusion\n', conf, problem=(13, 1) + ) def test_spaces(self): - conf = ('empty-lines: {max: 1, max-start: 0, max-end: 0}\n' - 'trailing-spaces: disable\n') + conf = ( + 'empty-lines: {max: 1, max-start: 0, max-end: 0}\n' + 'trailing-spaces: disable\n' + ) self.check('---\nintro\n\n \n\nconclusion\n', conf) self.check('---\nintro\n\n \n\n\nconclusion\n', conf, problem=(6, 1)) def test_empty_lines_at_start(self): - conf = ('empty-lines: {max: 2, max-start: 4, max-end: 0}\n' - 'document-start: disable\n') + conf = ( + 'empty-lines: {max: 2, max-start: 4, max-end: 0}\n' + 'document-start: disable\n' + ) self.check('\n\n\n\nnon empty\n', conf) self.check('\n\n\n\n\nnon empty\n', conf, problem=(5, 1)) - conf = ('empty-lines: {max: 2, max-start: 0, max-end: 0}\n' - 'document-start: disable\n') + conf = ( + 'empty-lines: {max: 2, max-start: 0, max-end: 0}\n' + 'document-start: disable\n' + ) self.check('non empty\n', conf) self.check('\nnon empty\n', conf, problem=(1, 1)) def test_empty_lines_at_end(self): - conf = ('empty-lines: {max: 2, max-start: 0, max-end: 4}\n' - 'document-start: disable\n') + conf = ( + 'empty-lines: {max: 2, max-start: 0, max-end: 4}\n' + 'document-start: disable\n' + ) self.check('non empty\n\n\n\n\n', conf) self.check('non empty\n\n\n\n\n\n', conf, problem=(6, 1)) - conf = ('empty-lines: {max: 2, max-start: 0, max-end: 0}\n' - 'document-start: disable\n') + conf = ( + 'empty-lines: {max: 2, max-start: 0, max-end: 0}\n' + 'document-start: disable\n' + ) self.check('non empty\n', conf) self.check('non empty\n\n', conf, problem=(2, 1)) def test_with_dos_newlines(self): - conf = ('empty-lines: {max: 2, max-start: 0, max-end: 0}\n' - 'new-lines: {type: dos}\n' - 'document-start: disable\n') + conf = ( + 'empty-lines: {max: 2, max-start: 0, max-end: 0}\n' + 'new-lines: {type: dos}\n' + 'document-start: disable\n' + ) self.check('---\r\n', conf) self.check('---\r\ntext\r\n\r\ntext\r\n', conf) - self.check('\r\n---\r\ntext\r\n\r\ntext\r\n', conf, - problem=(1, 1)) - self.check('\r\n\r\n\r\n---\r\ntext\r\n\r\ntext\r\n', conf, - problem=(3, 1)) - self.check('---\r\ntext\r\n\r\n\r\n\r\ntext\r\n', conf, - problem=(5, 1)) - self.check('---\r\ntext\r\n\r\n\r\n\r\n\r\n\r\n\r\ntext\r\n', conf, - problem=(8, 1)) - self.check('---\r\ntext\r\n\r\ntext\r\n\r\n', conf, - problem=(5, 1)) - self.check('---\r\ntext\r\n\r\ntext\r\n\r\n\r\n\r\n', conf, - problem=(7, 1)) + self.check('\r\n---\r\ntext\r\n\r\ntext\r\n', conf, problem=(1, 1)) + self.check('\r\n\r\n\r\n---\r\ntext\r\n\r\ntext\r\n', conf, problem=(3, 1)) + self.check('---\r\ntext\r\n\r\n\r\n\r\ntext\r\n', conf, problem=(5, 1)) + self.check( + '---\r\ntext\r\n\r\n\r\n\r\n\r\n\r\n\r\ntext\r\n', conf, problem=(8, 1) + ) + self.check('---\r\ntext\r\n\r\ntext\r\n\r\n', conf, problem=(5, 1)) + self.check('---\r\ntext\r\n\r\ntext\r\n\r\n\r\n\r\n', conf, problem=(7, 1)) diff --git a/tests/rules/test_empty_values.py b/tests/rules/test_empty_values.py index 653f218e..81cfe335 100644 --- a/tests/rules/test_empty_values.py +++ b/tests/rules/test_empty_values.py @@ -20,349 +20,297 @@ class EmptyValuesTestCase(RuleTestCase): rule_id = 'empty-values' def test_disabled(self): - conf = ('empty-values: disable\n' - 'braces: disable\n' - 'commas: disable\n') - self.check('---\n' - 'foo:\n', conf) - self.check('---\n' - 'foo:\n' - ' bar:\n', conf) - self.check('---\n' - '{a:}\n', conf) - self.check('---\n' - 'foo: {a:}\n', conf) - self.check('---\n' - '- {a:}\n' - '- {a:, b: 2}\n' - '- {a: 1, b:}\n' - '- {a: 1, b: , }\n', conf) - self.check('---\n' - '{a: {b: , c: {d: 4, e:}}, f:}\n', conf) + conf = 'empty-values: disable\n' 'braces: disable\n' 'commas: disable\n' + self.check('---\n' 'foo:\n', conf) + self.check('---\n' 'foo:\n' ' bar:\n', conf) + self.check('---\n' '{a:}\n', conf) + self.check('---\n' 'foo: {a:}\n', conf) + self.check( + '---\n' '- {a:}\n' '- {a:, b: 2}\n' '- {a: 1, b:}\n' '- {a: 1, b: , }\n', + conf, + ) + self.check('---\n' '{a: {b: , c: {d: 4, e:}}, f:}\n', conf) def test_in_block_mappings_disabled(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'foo:\n', conf) - self.check('---\n' - 'foo:\n' - 'bar: aaa\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'foo:\n', conf) + self.check('---\n' 'foo:\n' 'bar: aaa\n', conf) def test_in_block_mappings_single_line(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'implicitly-null:\n', conf, problem1=(2, 17)) - self.check('---\n' - 'implicitly-null:with-colons:in-key:\n', conf, - problem1=(2, 36)) - self.check('---\n' - 'implicitly-null:with-colons:in-key2:\n', conf, - problem1=(2, 37)) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'implicitly-null:\n', conf, problem1=(2, 17)) + self.check( + '---\n' 'implicitly-null:with-colons:in-key:\n', conf, problem1=(2, 36) + ) + self.check( + '---\n' 'implicitly-null:with-colons:in-key2:\n', conf, problem1=(2, 37) + ) def test_in_block_mappings_all_lines(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'foo:\n' - 'bar:\n' - 'foobar:\n', conf, problem1=(2, 5), - problem2=(3, 5), problem3=(4, 8)) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check( + '---\n' 'foo:\n' 'bar:\n' 'foobar:\n', + conf, + problem1=(2, 5), + problem2=(3, 5), + problem3=(4, 8), + ) def test_in_block_mappings_explicit_end_of_document(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'foo:\n' - '...\n', conf, problem1=(2, 5)) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'foo:\n' '...\n', conf, problem1=(2, 5)) def test_in_block_mappings_not_end_of_document(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'foo:\n' - 'bar:\n' - ' aaa\n', conf, problem1=(2, 5)) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'foo:\n' 'bar:\n' ' aaa\n', conf, problem1=(2, 5)) def test_in_block_mappings_different_level(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'foo:\n' - ' bar:\n' - 'aaa: bbb\n', conf, problem1=(3, 6)) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'foo:\n' ' bar:\n' 'aaa: bbb\n', conf, problem1=(3, 6)) def test_in_block_mappings_empty_flow_mapping(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n' - 'braces: disable\n' - 'commas: disable\n') - self.check('---\n' - 'foo: {a:}\n', conf) - self.check('---\n' - '- {a:, b: 2}\n' - '- {a: 1, b:}\n' - '- {a: 1, b: , }\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + 'braces: disable\n' + 'commas: disable\n' + ) + self.check('---\n' 'foo: {a:}\n', conf) + self.check('---\n' '- {a:, b: 2}\n' '- {a: 1, b:}\n' '- {a: 1, b: , }\n', conf) def test_in_block_mappings_empty_block_sequence(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'foo:\n' - ' -\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'foo:\n' ' -\n', conf) def test_in_block_mappings_not_empty_or_explicit_null(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'foo:\n' - ' bar:\n' - ' aaa\n', conf) - self.check('---\n' - 'explicitly-null: null\n', conf) - self.check('---\n' - 'explicitly-null:with-colons:in-key: null\n', conf) - self.check('---\n' - 'false-null: nulL\n', conf) - self.check('---\n' - 'empty-string: \'\'\n', conf) - self.check('---\n' - 'nullable-boolean: false\n', conf) - self.check('---\n' - 'nullable-int: 0\n', conf) - self.check('---\n' - 'First occurrence: &anchor Foo\n' - 'Second occurrence: *anchor\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'foo:\n' ' bar:\n' ' aaa\n', conf) + self.check('---\n' 'explicitly-null: null\n', conf) + self.check('---\n' 'explicitly-null:with-colons:in-key: null\n', conf) + self.check('---\n' 'false-null: nulL\n', conf) + self.check('---\n' "empty-string: ''\n", conf) + self.check('---\n' 'nullable-boolean: false\n', conf) + self.check('---\n' 'nullable-int: 0\n', conf) + self.check( + '---\n' 'First occurrence: &anchor Foo\n' 'Second occurrence: *anchor\n', + conf, + ) def test_in_block_mappings_various_explicit_null(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'null-alias: ~\n', conf) - self.check('---\n' - 'null-key1: {?: val}\n', conf) - self.check('---\n' - 'null-key2: {? !!null "": val}\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'null-alias: ~\n', conf) + self.check('---\n' 'null-key1: {?: val}\n', conf) + self.check('---\n' 'null-key2: {? !!null "": val}\n', conf) def test_in_block_mappings_comments(self): - conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n' - 'comments: disable\n') - self.check('---\n' - 'empty: # comment\n' - 'foo:\n' - ' bar: # comment\n', conf, - problem1=(2, 7), - problem2=(4, 7)) + conf = ( + 'empty-values: {forbid-in-block-mappings: true,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + 'comments: disable\n' + ) + self.check( + '---\n' 'empty: # comment\n' 'foo:\n' ' bar: # comment\n', + conf, + problem1=(2, 7), + problem2=(4, 7), + ) def test_in_flow_mappings_disabled(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n' - 'braces: disable\n' - 'commas: disable\n') - self.check('---\n' - '{a:}\n', conf) - self.check('---\n' - 'foo: {a:}\n', conf) - self.check('---\n' - '- {a:}\n' - '- {a:, b: 2}\n' - '- {a: 1, b:}\n' - '- {a: 1, b: , }\n', conf) - self.check('---\n' - '{a: {b: , c: {d: 4, e:}}, f:}\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + 'braces: disable\n' + 'commas: disable\n' + ) + self.check('---\n' '{a:}\n', conf) + self.check('---\n' 'foo: {a:}\n', conf) + self.check( + '---\n' '- {a:}\n' '- {a:, b: 2}\n' '- {a: 1, b:}\n' '- {a: 1, b: , }\n', + conf, + ) + self.check('---\n' '{a: {b: , c: {d: 4, e:}}, f:}\n', conf) def test_in_flow_mappings_single_line(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: true,\n' - ' forbid-in-block-sequences: false}\n' - 'braces: disable\n' - 'commas: disable\n') - self.check('---\n' - '{a:}\n', conf, - problem=(2, 4)) - self.check('---\n' - 'foo: {a:}\n', conf, - problem=(2, 9)) - self.check('---\n' - '- {a:}\n' - '- {a:, b: 2}\n' - '- {a: 1, b:}\n' - '- {a: 1, b: , }\n', conf, - problem1=(2, 6), - problem2=(3, 6), - problem3=(4, 12), - problem4=(5, 12)) - self.check('---\n' - '{a: {b: , c: {d: 4, e:}}, f:}\n', conf, - problem1=(2, 8), - problem2=(2, 23), - problem3=(2, 29)) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: true,\n' + ' forbid-in-block-sequences: false}\n' + 'braces: disable\n' + 'commas: disable\n' + ) + self.check('---\n' '{a:}\n', conf, problem=(2, 4)) + self.check('---\n' 'foo: {a:}\n', conf, problem=(2, 9)) + self.check( + '---\n' '- {a:}\n' '- {a:, b: 2}\n' '- {a: 1, b:}\n' '- {a: 1, b: , }\n', + conf, + problem1=(2, 6), + problem2=(3, 6), + problem3=(4, 12), + problem4=(5, 12), + ) + self.check( + '---\n' '{a: {b: , c: {d: 4, e:}}, f:}\n', + conf, + problem1=(2, 8), + problem2=(2, 23), + problem3=(2, 29), + ) def test_in_flow_mappings_multi_line(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: true,\n' - ' forbid-in-block-sequences: false}\n' - 'braces: disable\n' - 'commas: disable\n') - self.check('---\n' - 'foo: {\n' - ' a:\n' - '}\n', conf, - problem=(3, 5)) - self.check('---\n' - '{\n' - ' a: {\n' - ' b: ,\n' - ' c: {\n' - ' d: 4,\n' - ' e:\n' - ' }\n' - ' },\n' - ' f:\n' - '}\n', conf, - problem1=(4, 7), - problem2=(7, 9), - problem3=(10, 5)) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: true,\n' + ' forbid-in-block-sequences: false}\n' + 'braces: disable\n' + 'commas: disable\n' + ) + self.check('---\n' 'foo: {\n' ' a:\n' '}\n', conf, problem=(3, 5)) + self.check( + '---\n' + '{\n' + ' a: {\n' + ' b: ,\n' + ' c: {\n' + ' d: 4,\n' + ' e:\n' + ' }\n' + ' },\n' + ' f:\n' + '}\n', + conf, + problem1=(4, 7), + problem2=(7, 9), + problem3=(10, 5), + ) def test_in_flow_mappings_various_explicit_null(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: true,\n' - ' forbid-in-block-sequences: false}\n' - 'braces: disable\n' - 'commas: disable\n') - self.check('---\n' - '{explicit-null: null}\n', conf) - self.check('---\n' - '{null-alias: ~}\n', conf) - self.check('---\n' - 'null-key1: {?: val}\n', conf) - self.check('---\n' - 'null-key2: {? !!null "": val}\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: true,\n' + ' forbid-in-block-sequences: false}\n' + 'braces: disable\n' + 'commas: disable\n' + ) + self.check('---\n' '{explicit-null: null}\n', conf) + self.check('---\n' '{null-alias: ~}\n', conf) + self.check('---\n' 'null-key1: {?: val}\n', conf) + self.check('---\n' 'null-key2: {? !!null "": val}\n', conf) def test_in_flow_mappings_comments(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: true,\n' - ' forbid-in-block-sequences: false}\n' - 'braces: disable\n' - 'commas: disable\n' - 'comments: disable\n') - self.check('---\n' - '{\n' - ' a: {\n' - ' b: , # comment\n' - ' c: {\n' - ' d: 4, # comment\n' - ' e: # comment\n' - ' }\n' - ' },\n' - ' f: # comment\n' - '}\n', conf, - problem1=(4, 7), - problem2=(7, 9), - problem3=(10, 5)) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: true,\n' + ' forbid-in-block-sequences: false}\n' + 'braces: disable\n' + 'commas: disable\n' + 'comments: disable\n' + ) + self.check( + '---\n' + '{\n' + ' a: {\n' + ' b: , # comment\n' + ' c: {\n' + ' d: 4, # comment\n' + ' e: # comment\n' + ' }\n' + ' },\n' + ' f: # comment\n' + '}\n', + conf, + problem1=(4, 7), + problem2=(7, 9), + problem3=(10, 5), + ) def test_in_block_sequences_disabled(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: false}\n') - self.check('---\n' - 'foo:\n' - ' - bar\n' - ' -\n', conf) - self.check('---\n' - 'foo:\n' - ' -\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' + ) + self.check('---\n' 'foo:\n' ' - bar\n' ' -\n', conf) + self.check('---\n' 'foo:\n' ' -\n', conf) def test_in_block_sequences_primative_item(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: true}\n') - self.check('---\n' - 'foo:\n' - ' -\n', conf, - problem=(3, 4)) - self.check('---\n' - 'foo:\n' - ' - bar\n' - ' -\n', conf, - problem=(4, 4)) - self.check('---\n' - 'foo:\n' - ' - 1\n' - ' - 2\n' - ' -\n', conf, - problem=(5, 4)) - self.check('---\n' - 'foo:\n' - ' - true\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: true}\n' + ) + self.check('---\n' 'foo:\n' ' -\n', conf, problem=(3, 4)) + self.check('---\n' 'foo:\n' ' - bar\n' ' -\n', conf, problem=(4, 4)) + self.check('---\n' 'foo:\n' ' - 1\n' ' - 2\n' ' -\n', conf, problem=(5, 4)) + self.check('---\n' 'foo:\n' ' - true\n', conf) def test_in_block_sequences_complex_objects(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: true}\n') - self.check('---\n' - 'foo:\n' - ' - a: 1\n', conf) - self.check('---\n' - 'foo:\n' - ' - a: 1\n' - ' -\n', conf, - problem=(4, 4)) - self.check('---\n' - 'foo:\n' - ' - a: 1\n' - ' b: 2\n' - ' -\n', conf, - problem=(5, 4)) - self.check('---\n' - 'foo:\n' - ' - a: 1\n' - ' - b: 2\n' - ' -\n', conf, - problem=(5, 4)) - self.check('---\n' - 'foo:\n' - ' - - a\n' - ' - b: 2\n' - ' -\n', conf, - problem=(5, 6)) - self.check('---\n' - 'foo:\n' - ' - - a\n' - ' - b: 2\n' - ' -\n', conf, - problem=(5, 4)) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: true}\n' + ) + self.check('---\n' 'foo:\n' ' - a: 1\n', conf) + self.check('---\n' 'foo:\n' ' - a: 1\n' ' -\n', conf, problem=(4, 4)) + self.check( + '---\n' 'foo:\n' ' - a: 1\n' ' b: 2\n' ' -\n', conf, problem=(5, 4) + ) + self.check( + '---\n' 'foo:\n' ' - a: 1\n' ' - b: 2\n' ' -\n', conf, problem=(5, 4) + ) + self.check( + '---\n' 'foo:\n' ' - - a\n' ' - b: 2\n' ' -\n', conf, problem=(5, 6) + ) + self.check( + '---\n' 'foo:\n' ' - - a\n' ' - b: 2\n' ' -\n', conf, problem=(5, 4) + ) def test_in_block_sequences_various_explicit_null(self): - conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: false,\n' - ' forbid-in-block-sequences: true}\n') - self.check('---\n' - 'foo:\n' - ' - null\n', conf) - self.check('---\n' - '- null\n', conf) - self.check('---\n' - 'foo:\n' - ' - bar: null\n' - ' - null\n', conf) - self.check('---\n' - '- null\n' - '- null\n', conf) - self.check('---\n' - '- - null\n' - ' - null\n', conf) + conf = ( + 'empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: true}\n' + ) + self.check('---\n' 'foo:\n' ' - null\n', conf) + self.check('---\n' '- null\n', conf) + self.check('---\n' 'foo:\n' ' - bar: null\n' ' - null\n', conf) + self.check('---\n' '- null\n' '- null\n', conf) + self.check('---\n' '- - null\n' ' - null\n', conf) diff --git a/tests/rules/test_float_values.py b/tests/rules/test_float_values.py index 8aa980cd..eaadf325 100644 --- a/tests/rules/test_float_values.py +++ b/tests/rules/test_float_values.py @@ -21,13 +21,7 @@ class FloatValuesTestCase(RuleTestCase): def test_disabled(self): conf = 'float-values: disable\n' - self.check('---\n' - '- 0.0\n' - '- .NaN\n' - '- .INF\n' - '- .1\n' - '- 10e-6\n', - conf) + self.check('---\n' '- 0.0\n' '- .NaN\n' '- .INF\n' '- .1\n' '- 10e-6\n', conf) def test_numeral_before_decimal(self): conf = ( @@ -35,21 +29,24 @@ def test_numeral_before_decimal(self): ' require-numeral-before-decimal: true\n' ' forbid-scientific-notation: false\n' ' forbid-nan: false\n' - ' forbid-inf: false\n') - self.check('---\n' - '- 0.0\n' - '- .1\n' - '- \'.1\'\n' - '- string.1\n' - '- .1string\n' - '- !custom_tag .2\n' - '- &angle1 0.0\n' - '- *angle1\n' - '- &angle2 .3\n' - '- *angle2\n', - conf, - problem1=(3, 3), - problem2=(10, 11)) + ' forbid-inf: false\n' + ) + self.check( + '---\n' + '- 0.0\n' + '- .1\n' + "- '.1'\n" + '- string.1\n' + '- .1string\n' + '- !custom_tag .2\n' + '- &angle1 0.0\n' + '- *angle1\n' + '- &angle2 .3\n' + '- *angle2\n', + conf, + problem1=(3, 3), + problem2=(10, 11), + ) def test_scientific_notation(self): conf = ( @@ -57,26 +54,29 @@ def test_scientific_notation(self): ' require-numeral-before-decimal: false\n' ' forbid-scientific-notation: true\n' ' forbid-nan: false\n' - ' forbid-inf: false\n') - self.check('---\n' - '- 10e6\n' - '- 10e-6\n' - '- 0.00001\n' - '- \'10e-6\'\n' - '- string10e-6\n' - '- 10e-6string\n' - '- !custom_tag 10e-6\n' - '- &angle1 0.000001\n' - '- *angle1\n' - '- &angle2 10e-6\n' - '- *angle2\n' - '- &angle3 10e6\n' - '- *angle3\n', - conf, - problem1=(2, 3), - problem2=(3, 3), - problem3=(11, 11), - problem4=(13, 11)) + ' forbid-inf: false\n' + ) + self.check( + '---\n' + '- 10e6\n' + '- 10e-6\n' + '- 0.00001\n' + "- '10e-6'\n" + '- string10e-6\n' + '- 10e-6string\n' + '- !custom_tag 10e-6\n' + '- &angle1 0.000001\n' + '- *angle1\n' + '- &angle2 10e-6\n' + '- *angle2\n' + '- &angle3 10e6\n' + '- *angle3\n', + conf, + problem1=(2, 3), + problem2=(3, 3), + problem3=(11, 11), + problem4=(13, 11), + ) def test_nan(self): conf = ( @@ -84,20 +84,23 @@ def test_nan(self): ' require-numeral-before-decimal: false\n' ' forbid-scientific-notation: false\n' ' forbid-nan: true\n' - ' forbid-inf: false\n') - self.check('---\n' - '- .NaN\n' - '- .NAN\n' - '- \'.NaN\'\n' - '- a.NaN\n' - '- .NaNa\n' - '- !custom_tag .NaN\n' - '- &angle .nan\n' - '- *angle\n', - conf, - problem1=(2, 3), - problem2=(3, 3), - problem3=(8, 10)) + ' forbid-inf: false\n' + ) + self.check( + '---\n' + '- .NaN\n' + '- .NAN\n' + "- '.NaN'\n" + '- a.NaN\n' + '- .NaNa\n' + '- !custom_tag .NaN\n' + '- &angle .nan\n' + '- *angle\n', + conf, + problem1=(2, 3), + problem2=(3, 3), + problem3=(8, 10), + ) def test_inf(self): conf = ( @@ -105,24 +108,27 @@ def test_inf(self): ' require-numeral-before-decimal: false\n' ' forbid-scientific-notation: false\n' ' forbid-nan: false\n' - ' forbid-inf: true\n') - self.check('---\n' - '- .inf\n' - '- .INF\n' - '- -.inf\n' - '- -.INF\n' - '- \'.inf\'\n' - '- ∞.infinity\n' - '- .infinity∞\n' - '- !custom_tag .inf\n' - '- &angle .inf\n' - '- *angle\n' - '- &angle -.inf\n' - '- *angle\n', - conf, - problem1=(2, 3), - problem2=(3, 3), - problem3=(4, 3), - problem4=(5, 3), - problem5=(10, 10), - problem6=(12, 10)) + ' forbid-inf: true\n' + ) + self.check( + '---\n' + '- .inf\n' + '- .INF\n' + '- -.inf\n' + '- -.INF\n' + "- '.inf'\n" + '- ∞.infinity\n' + '- .infinity∞\n' + '- !custom_tag .inf\n' + '- &angle .inf\n' + '- *angle\n' + '- &angle -.inf\n' + '- *angle\n', + conf, + problem1=(2, 3), + problem2=(3, 3), + problem3=(4, 3), + problem4=(5, 3), + problem5=(10, 10), + problem6=(12, 10), + ) diff --git a/tests/rules/test_hyphens.py b/tests/rules/test_hyphens.py index a0ec5775..416d2316 100644 --- a/tests/rules/test_hyphens.py +++ b/tests/rules/test_hyphens.py @@ -21,85 +21,56 @@ class HyphenTestCase(RuleTestCase): def test_disabled(self): conf = 'hyphens: disable' - self.check('---\n' - '- elem1\n' - '- elem2\n', conf) - self.check('---\n' - '- elem1\n' - '- elem2\n', conf) - self.check('---\n' - '- elem1\n' - '- elem2\n', conf) - self.check('---\n' - '- elem1\n' - '- elem2\n', conf) - self.check('---\n' - 'object:\n' - ' - elem1\n' - ' - elem2\n', conf) - self.check('---\n' - 'object:\n' - ' - elem1\n' - ' - elem2\n', conf) - self.check('---\n' - 'object:\n' - ' subobject:\n' - ' - elem1\n' - ' - elem2\n', conf) - self.check('---\n' - 'object:\n' - ' subobject:\n' - ' - elem1\n' - ' - elem2\n', conf) + self.check('---\n' '- elem1\n' '- elem2\n', conf) + self.check('---\n' '- elem1\n' '- elem2\n', conf) + self.check('---\n' '- elem1\n' '- elem2\n', conf) + self.check('---\n' '- elem1\n' '- elem2\n', conf) + self.check('---\n' 'object:\n' ' - elem1\n' ' - elem2\n', conf) + self.check('---\n' 'object:\n' ' - elem1\n' ' - elem2\n', conf) + self.check( + '---\n' 'object:\n' ' subobject:\n' ' - elem1\n' ' - elem2\n', conf + ) + self.check( + '---\n' 'object:\n' ' subobject:\n' ' - elem1\n' ' - elem2\n', conf + ) def test_enabled(self): conf = 'hyphens: {max-spaces-after: 1}' - self.check('---\n' - '- elem1\n' - '- elem2\n', conf) - self.check('---\n' - '- elem1\n' - '- elem2\n', conf, problem=(3, 3)) - self.check('---\n' - '- elem1\n' - '- elem2\n', conf, problem1=(2, 3), problem2=(3, 3)) - self.check('---\n' - '- elem1\n' - '- elem2\n', conf, problem=(2, 3)) - self.check('---\n' - 'object:\n' - ' - elem1\n' - ' - elem2\n', conf, problem=(4, 5)) - self.check('---\n' - 'object:\n' - ' - elem1\n' - ' - elem2\n', conf, problem1=(3, 5), problem2=(4, 5)) - self.check('---\n' - 'object:\n' - ' subobject:\n' - ' - elem1\n' - ' - elem2\n', conf, problem=(5, 7)) - self.check('---\n' - 'object:\n' - ' subobject:\n' - ' - elem1\n' - ' - elem2\n', conf, problem1=(4, 7), problem2=(5, 7)) + self.check('---\n' '- elem1\n' '- elem2\n', conf) + self.check('---\n' '- elem1\n' '- elem2\n', conf, problem=(3, 3)) + self.check( + '---\n' '- elem1\n' '- elem2\n', conf, problem1=(2, 3), problem2=(3, 3) + ) + self.check('---\n' '- elem1\n' '- elem2\n', conf, problem=(2, 3)) + self.check( + '---\n' 'object:\n' ' - elem1\n' ' - elem2\n', conf, problem=(4, 5) + ) + self.check( + '---\n' 'object:\n' ' - elem1\n' ' - elem2\n', + conf, + problem1=(3, 5), + problem2=(4, 5), + ) + self.check( + '---\n' 'object:\n' ' subobject:\n' ' - elem1\n' ' - elem2\n', + conf, + problem=(5, 7), + ) + self.check( + '---\n' 'object:\n' ' subobject:\n' ' - elem1\n' ' - elem2\n', + conf, + problem1=(4, 7), + problem2=(5, 7), + ) def test_max_3(self): conf = 'hyphens: {max-spaces-after: 3}' - self.check('---\n' - '- elem1\n' - '- elem2\n', conf) - self.check('---\n' - '- elem1\n' - '- elem2\n', conf, problem=(2, 5)) - self.check('---\n' - 'a:\n' - ' b:\n' - ' - elem1\n' - ' - elem2\n', conf) - self.check('---\n' - 'a:\n' - ' b:\n' - ' - elem1\n' - ' - elem2\n', conf, problem1=(4, 9), problem2=(5, 9)) + self.check('---\n' '- elem1\n' '- elem2\n', conf) + self.check('---\n' '- elem1\n' '- elem2\n', conf, problem=(2, 5)) + self.check('---\n' 'a:\n' ' b:\n' ' - elem1\n' ' - elem2\n', conf) + self.check( + '---\n' 'a:\n' ' b:\n' ' - elem1\n' ' - elem2\n', + conf, + problem1=(4, 9), + problem2=(5, 9), + ) diff --git a/tests/rules/test_indentation.py b/tests/rules/test_indentation.py index 3e929bf2..06b3a7f9 100644 --- a/tests/rules/test_indentation.py +++ b/tests/rules/test_indentation.py @@ -34,20 +34,25 @@ def format_stack(self, stack): return ' '.join(map(str, stack[1:])) def full_stack(self, source): - conf = {'spaces': 2, 'indent-sequences': True, - 'check-multi-line-strings': False} + conf = { + 'spaces': 2, + 'indent-sequences': True, + 'check-multi-line-strings': False, + } context = {} output = '' - for elem in [t for t in token_or_comment_generator(source) - if not isinstance(t, Comment)]: - list(check(conf, elem.curr, elem.prev, elem.next, elem.nextnext, - context)) - - token_type = (elem.curr.__class__.__name__ - .replace('Token', '') - .replace('Block', 'B').replace('Flow', 'F') - .replace('Sequence', 'Seq') - .replace('Mapping', 'Map')) + for elem in [ + t for t in token_or_comment_generator(source) if not isinstance(t, Comment) + ]: + list(check(conf, elem.curr, elem.prev, elem.next, elem.nextnext, context)) + + token_type = ( + elem.curr.__class__.__name__.replace('Token', '') + .replace('Block', 'B') + .replace('Flow', 'F') + .replace('Sequence', 'Seq') + .replace('Mapping', 'Map') + ) if token_type in ('StreamStart', 'StreamEnd'): continue stack = self.format_stack(context['stack']) @@ -62,7 +67,8 @@ def test_simple_mapping(self): ' Scalar B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:5\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( self.full_stack(' key: val\n'), @@ -71,13 +77,12 @@ def test_simple_mapping(self): ' Scalar B_MAP:5 KEY:5\n' ' Value B_MAP:5 KEY:5 VAL:10\n' ' Scalar B_MAP:5\n' - ' BEnd \n') + ' BEnd \n', + ) def test_simple_sequence(self): self.assertMultiLineEqual( - self.full_stack('- 1\n' - '- 2\n' - '- 3\n'), + self.full_stack('- 1\n' '- 2\n' '- 3\n'), 'BSeqStart B_SEQ:0\n' ' BEntry B_SEQ:0 B_ENT:2\n' ' Scalar B_SEQ:0\n' @@ -85,12 +90,11 @@ def test_simple_sequence(self): ' Scalar B_SEQ:0\n' ' BEntry B_SEQ:0 B_ENT:2\n' ' Scalar B_SEQ:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('key:\n' - ' - 1\n' - ' - 2\n'), + self.full_stack('key:\n' ' - 1\n' ' - 2\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -101,7 +105,8 @@ def test_simple_sequence(self): ' BEntry B_MAP:0 KEY:0 VAL:2 B_SEQ:2 B_ENT:4\n' ' Scalar B_MAP:0 KEY:0 VAL:2 B_SEQ:2\n' ' BEnd B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) def test_non_indented_sequences(self): # There seems to be a bug in pyyaml: depending on the indentation, a @@ -117,9 +122,7 @@ def test_non_indented_sequences(self): # So, yamllint must create fake 'B_SEQ'. This test makes sure it does. self.assertMultiLineEqual( - self.full_stack('usr:\n' - ' - lib\n' - 'var: cache\n'), + self.full_stack('usr:\n' ' - lib\n' 'var: cache\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -132,11 +135,11 @@ def test_non_indented_sequences(self): ' Scalar B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:5\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('usr:\n' - '- lib\n'), + self.full_stack('usr:\n' '- lib\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -145,12 +148,11 @@ def test_non_indented_sequences(self): ' BEntry B_MAP:0 KEY:0 VAL:2 B_SEQ:0 B_ENT:2\n' ' Scalar B_MAP:0\n' # missing BEnd here - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('usr:\n' - '- lib\n' - 'var: cache\n'), + self.full_stack('usr:\n' '- lib\n' 'var: cache\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -163,11 +165,11 @@ def test_non_indented_sequences(self): ' Scalar B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:5\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('usr:\n' - '- []\n'), + self.full_stack('usr:\n' '- []\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -177,12 +179,11 @@ def test_non_indented_sequences(self): 'FSeqStart B_MAP:0 KEY:0 VAL:2 B_SEQ:0 B_ENT:2 F_SEQ:3\n' ' FSeqEnd B_MAP:0\n' # missing BEnd here - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('usr:\n' - '- k:\n' - ' v\n'), + self.full_stack('usr:\n' '- k:\n' ' v\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -196,14 +197,12 @@ def test_non_indented_sequences(self): ' Scalar B_MAP:0 KEY:0 VAL:2 B_SEQ:0 B_ENT:2 B_MAP:2\n' ' BEnd B_MAP:0\n' # missing BEnd here - ' BEnd \n') + ' BEnd \n', + ) def test_flows(self): self.assertMultiLineEqual( - self.full_stack('usr: [\n' - ' {k:\n' - ' v}\n' - ' ]\n'), + self.full_stack('usr: [\n' ' {k:\n' ' v}\n' ' ]\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -216,7 +215,8 @@ def test_flows(self): ' Scalar B_MAP:0 KEY:0 VAL:5 F_SEQ:2 F_MAP:3\n' ' FMapEnd B_MAP:0 KEY:0 VAL:5 F_SEQ:2\n' ' FSeqEnd B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) def test_anchors(self): self.assertMultiLineEqual( @@ -227,18 +227,19 @@ def test_anchors(self): ' Value B_MAP:0 KEY:0 VAL:5\n' ' Anchor B_MAP:0 KEY:0 VAL:5\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('key: &anchor\n' - ' value\n'), + self.full_stack('key: &anchor\n' ' value\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:2\n' ' Anchor B_MAP:0 KEY:0 VAL:2\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( self.full_stack('- &anchor value\n'), @@ -246,21 +247,20 @@ def test_anchors(self): ' BEntry B_SEQ:0 B_ENT:2\n' ' Anchor B_SEQ:0 B_ENT:2\n' ' Scalar B_SEQ:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('- &anchor\n' - ' value\n'), + self.full_stack('- &anchor\n' ' value\n'), 'BSeqStart B_SEQ:0\n' ' BEntry B_SEQ:0 B_ENT:2\n' ' Anchor B_SEQ:0 B_ENT:2\n' ' Scalar B_SEQ:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('- &anchor\n' - ' - 1\n' - ' - 2\n'), + self.full_stack('- &anchor\n' ' - 1\n' ' - 2\n'), 'BSeqStart B_SEQ:0\n' ' BEntry B_SEQ:0 B_ENT:2\n' ' Anchor B_SEQ:0 B_ENT:2\n' @@ -270,24 +270,22 @@ def test_anchors(self): ' BEntry B_SEQ:0 B_ENT:2 B_SEQ:2 B_ENT:4\n' ' Scalar B_SEQ:0 B_ENT:2 B_SEQ:2\n' ' BEnd B_SEQ:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('&anchor key:\n' - ' value\n'), + self.full_stack('&anchor key:\n' ' value\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Anchor B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:2\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('pre:\n' - ' &anchor1 0\n' - '&anchor2 key:\n' - ' value\n'), + self.full_stack('pre:\n' ' &anchor1 0\n' '&anchor2 key:\n' ' value\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -299,13 +297,13 @@ def test_anchors(self): ' Scalar B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:2\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('sequence: &anchor\n' - '- entry\n' - '- &anchor\n' - ' - nested\n'), + self.full_stack( + 'sequence: &anchor\n' '- entry\n' '- &anchor\n' ' - nested\n' + ), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -321,7 +319,8 @@ def test_anchors(self): ' Scalar B_MAP:0 KEY:0 VAL:2 B_SEQ:0 B_ENT:2 B_SEQ:2\n' ' BEnd B_MAP:0\n' # missing BEnd here - ' BEnd \n') + ' BEnd \n', + ) def test_tags(self): self.assertMultiLineEqual( @@ -332,11 +331,11 @@ def test_tags(self): ' Value B_MAP:0 KEY:0 VAL:5\n' ' Tag B_MAP:0 KEY:0 VAL:5\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('- !!map # Block collection\n' - ' foo : bar\n'), + self.full_stack('- !!map # Block collection\n' ' foo : bar\n'), 'BSeqStart B_SEQ:0\n' ' BEntry B_SEQ:0 B_ENT:2\n' ' Tag B_SEQ:0 B_ENT:2\n' @@ -346,11 +345,11 @@ def test_tags(self): ' Value B_SEQ:0 B_ENT:2 B_MAP:2 KEY:2 VAL:8\n' ' Scalar B_SEQ:0 B_ENT:2 B_MAP:2\n' ' BEnd B_SEQ:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('- !!seq\n' - ' - nested item\n'), + self.full_stack('- !!seq\n' ' - nested item\n'), 'BSeqStart B_SEQ:0\n' ' BEntry B_SEQ:0 B_ENT:2\n' ' Tag B_SEQ:0 B_ENT:2\n' @@ -358,13 +357,11 @@ def test_tags(self): ' BEntry B_SEQ:0 B_ENT:2 B_SEQ:2 B_ENT:4\n' ' Scalar B_SEQ:0 B_ENT:2 B_SEQ:2\n' ' BEnd B_SEQ:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( - self.full_stack('sequence: !!seq\n' - '- entry\n' - '- !!seq\n' - ' - nested\n'), + self.full_stack('sequence: !!seq\n' '- entry\n' '- !!seq\n' ' - nested\n'), 'BMapStart B_MAP:0\n' ' Key B_MAP:0 KEY:0\n' ' Scalar B_MAP:0 KEY:0\n' @@ -380,7 +377,8 @@ def test_tags(self): ' Scalar B_MAP:0 KEY:0 VAL:2 B_SEQ:0 B_ENT:2 B_SEQ:2\n' ' BEnd B_MAP:0\n' # missing BEnd here - ' BEnd \n') + ' BEnd \n', + ) def test_flows_imbrication(self): self.assertMultiLineEqual( @@ -389,7 +387,8 @@ def test_flows_imbrication(self): 'FSeqStart F_SEQ:1 F_SEQ:2\n' ' Scalar F_SEQ:1 F_SEQ:2\n' ' FSeqEnd F_SEQ:1\n' - ' FSeqEnd \n') + ' FSeqEnd \n', + ) self.assertMultiLineEqual( self.full_stack('[[val], [val2]]\n'), @@ -401,7 +400,8 @@ def test_flows_imbrication(self): 'FSeqStart F_SEQ:1 F_SEQ:9\n' ' Scalar F_SEQ:1 F_SEQ:9\n' ' FSeqEnd F_SEQ:1\n' - ' FSeqEnd \n') + ' FSeqEnd \n', + ) self.assertMultiLineEqual( self.full_stack('{{key}}\n'), @@ -409,7 +409,8 @@ def test_flows_imbrication(self): 'FMapStart F_MAP:1 F_MAP:2\n' ' Scalar F_MAP:1 F_MAP:2\n' ' FMapEnd F_MAP:1\n' - ' FMapEnd \n') + ' FMapEnd \n', + ) self.assertMultiLineEqual( self.full_stack('[key]: value\n'), @@ -420,7 +421,8 @@ def test_flows_imbrication(self): ' FSeqEnd B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:7\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( self.full_stack('[[key]]: value\n'), @@ -433,7 +435,8 @@ def test_flows_imbrication(self): ' FSeqEnd B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:9\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( self.full_stack('{key}: value\n'), @@ -444,7 +447,8 @@ def test_flows_imbrication(self): ' FMapEnd B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:7\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( self.full_stack('{key: value}: value\n'), @@ -458,7 +462,8 @@ def test_flows_imbrication(self): ' FMapEnd B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:14\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( self.full_stack('{{key}}: value\n'), @@ -471,7 +476,8 @@ def test_flows_imbrication(self): ' FMapEnd B_MAP:0 KEY:0\n' ' Value B_MAP:0 KEY:0 VAL:9\n' ' Scalar B_MAP:0\n' - ' BEnd \n') + ' BEnd \n', + ) self.assertMultiLineEqual( self.full_stack('{{key}: val, {key2}: {val2}}\n'), 'FMapStart F_MAP:1\n' @@ -490,7 +496,8 @@ def test_flows_imbrication(self): 'FMapStart F_MAP:1 KEY:1 VAL:21 F_MAP:22\n' ' Scalar F_MAP:1 KEY:1 VAL:21 F_MAP:22\n' ' FMapEnd F_MAP:1\n' - ' FMapEnd \n') + ' FMapEnd \n', + ) self.assertMultiLineEqual( self.full_stack('{[{{[val]}}, [{[key]: val2}]]}\n'), @@ -515,7 +522,8 @@ def test_flows_imbrication(self): ' FMapEnd F_MAP:1 F_SEQ:2 F_SEQ:14\n' ' FSeqEnd F_MAP:1 F_SEQ:2\n' ' FSeqEnd F_MAP:1\n' - ' FMapEnd \n') + ' FMapEnd \n', + ) class IndentationTestCase(RuleTestCase): @@ -523,571 +531,651 @@ class IndentationTestCase(RuleTestCase): def test_disabled(self): conf = 'indentation: disable' - self.check('---\n' - 'object:\n' - ' k1: v1\n' - 'obj2:\n' - ' k2:\n' - ' - 8\n' - ' k3:\n' - ' val\n' - '...\n', conf) - self.check('---\n' - ' o:\n' - ' k1: v1\n' - ' p:\n' - ' k3:\n' - ' val\n' - '...\n', conf) - self.check('---\n' - ' - o:\n' - ' k1: v1\n' - ' - p: kdjf\n' - ' - q:\n' - ' k3:\n' - ' - val\n' - '...\n', conf) + self.check( + '---\n' + 'object:\n' + ' k1: v1\n' + 'obj2:\n' + ' k2:\n' + ' - 8\n' + ' k3:\n' + ' val\n' + '...\n', + conf, + ) + self.check( + '---\n' ' o:\n' ' k1: v1\n' ' p:\n' ' k3:\n' ' val\n' '...\n', + conf, + ) + self.check( + '---\n' + ' - o:\n' + ' k1: v1\n' + ' - p: kdjf\n' + ' - q:\n' + ' k3:\n' + ' - val\n' + '...\n', + conf, + ) def test_one_space(self): conf = 'indentation: {spaces: 1, indent-sequences: false}' - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + ) conf = 'indentation: {spaces: 1, indent-sequences: true}' - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + ) def test_two_spaces(self): conf = 'indentation: {spaces: 2, indent-sequences: false}' - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - ' k4:\n' - ' -\n' - ' k5: v3\n' - '...\n', conf) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + ' k4:\n' + ' -\n' + ' k5: v3\n' + '...\n', + conf, + ) conf = 'indentation: {spaces: 2, indent-sequences: true}' - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + ) def test_three_spaces(self): conf = 'indentation: {spaces: 3, indent-sequences: false}' - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + ) conf = 'indentation: {spaces: 3, indent-sequences: true}' - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + ) def test_consistent_spaces(self): - conf = ('indentation: {spaces: consistent,\n' - ' indent-sequences: whatever}\n' - 'document-start: disable\n') - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf) - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf) - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - ' - b\n' - ' k2: v2\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf) - self.check('first is not indented:\n' - ' value is indented\n', conf) - self.check('first is not indented:\n' - ' value:\n' - ' is indented\n', conf) - self.check('- first is already indented:\n' - ' value is indented too\n', conf) - self.check('- first is already indented:\n' - ' value:\n' - ' is indented too\n', conf) - self.check('- first is already indented:\n' - ' value:\n' - ' is indented too\n', conf, problem=(3, 14)) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem=(7, 5)) - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' indent-sequences: whatever}\n' + 'document-start: disable\n' + ) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'object:\n' + ' k1:\n' + ' - a\n' + ' - b\n' + ' k2: v2\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + ) + self.check('first is not indented:\n' ' value is indented\n', conf) + self.check( + 'first is not indented:\n' ' value:\n' ' is indented\n', conf + ) + self.check('- first is already indented:\n' ' value is indented too\n', conf) + self.check( + '- first is already indented:\n' + ' value:\n' + ' is indented too\n', + conf, + ) + self.check( + '- first is already indented:\n' + ' value:\n' + ' is indented too\n', + conf, + problem=(3, 14), + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem=(7, 5), + ) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + ) def test_consistent_spaces_and_indent_sequences(self): conf = 'indentation: {spaces: consistent, indent-sequences: true}' - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem1=(3, 1)) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem1=(7, 5)) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf, problem1=(7, 1)) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem1=(3, 1), + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem1=(7, 5), + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + problem1=(7, 1), + ) conf = 'indentation: {spaces: consistent, indent-sequences: false}' - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem1=(7, 5)) - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem1=(7, 3)) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf, problem1=(3, 3)) - - conf = ('indentation: {spaces: consistent,\n' - ' indent-sequences: consistent}') - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem1=(7, 5)) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf, problem1=(7, 1)) - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem1=(7, 5)) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem1=(7, 5), + ) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem1=(7, 3), + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + problem1=(3, 3), + ) + + conf = ( + 'indentation: {spaces: consistent,\n' + ' indent-sequences: consistent}' + ) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem1=(7, 5), + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + problem1=(7, 1), + ) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem1=(7, 5), + ) conf = 'indentation: {spaces: consistent, indent-sequences: whatever}' - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf) - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem1=(7, 5)) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + ) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem1=(7, 5), + ) def test_indent_sequences_whatever(self): conf = 'indentation: {spaces: 4, indent-sequences: whatever}' - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem=(3, 3)) - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem=(7, 3)) - self.check('---\n' - 'list:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - '- a\n' - '- b\n' - '- c\n', conf, problem=(6, 1, 'syntax')) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem=(3, 3), + ) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem=(7, 3), + ) + self.check( + '---\n' + 'list:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + '- a\n' + '- b\n' + '- c\n', + conf, + problem=(6, 1, 'syntax'), + ) def test_indent_sequences_consistent(self): conf = 'indentation: {spaces: 4, indent-sequences: consistent}' - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list:\n' - ' two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list:\n' - ' two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf) - self.check('---\n' - 'list one:\n' - '- 1\n' - '- 2\n' - '- 3\n' - 'list two:\n' - ' - a\n' - ' - b\n' - ' - c\n', conf, problem=(7, 5)) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf, problem=(7, 1)) - self.check('---\n' - 'list one:\n' - ' - 1\n' - ' - 2\n' - ' - 3\n' - 'list two:\n' - '- a\n' - '- b\n' - '- c\n', conf, problem1=(3, 2), problem2=(7, 1)) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list:\n' + ' two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list:\n' + ' two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + ) + self.check( + '---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', + conf, + problem=(7, 5), + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + problem=(7, 1), + ) + self.check( + '---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', + conf, + problem1=(3, 2), + problem2=(7, 1), + ) def test_direct_flows(self): # flow: [ ... # ] conf = 'indentation: {spaces: consistent}' - self.check('---\n' - 'a: {x: 1,\n' - ' y,\n' - ' z: 1}\n', conf) - self.check('---\n' - 'a: {x: 1,\n' - ' y,\n' - ' z: 1}\n', conf, problem=(3, 4)) - self.check('---\n' - 'a: {x: 1,\n' - ' y,\n' - ' z: 1}\n', conf, problem=(3, 6)) - self.check('---\n' - 'a: {x: 1,\n' - ' y, z: 1}\n', conf, problem=(3, 3)) - self.check('---\n' - 'a: {x: 1,\n' - ' y, z: 1\n' - '}\n', conf) - self.check('---\n' - 'a: {x: 1,\n' - ' y, z: 1\n' - '}\n', conf, problem=(3, 3)) - self.check('---\n' - 'a: [x,\n' - ' y,\n' - ' z]\n', conf) - self.check('---\n' - 'a: [x,\n' - ' y,\n' - ' z]\n', conf, problem=(3, 4)) - self.check('---\n' - 'a: [x,\n' - ' y,\n' - ' z]\n', conf, problem=(3, 6)) - self.check('---\n' - 'a: [x,\n' - ' y, z]\n', conf, problem=(3, 3)) - self.check('---\n' - 'a: [x,\n' - ' y, z\n' - ']\n', conf) - self.check('---\n' - 'a: [x,\n' - ' y, z\n' - ']\n', conf, problem=(3, 3)) + self.check('---\n' 'a: {x: 1,\n' ' y,\n' ' z: 1}\n', conf) + self.check('---\n' 'a: {x: 1,\n' ' y,\n' ' z: 1}\n', conf, problem=(3, 4)) + self.check( + '---\n' 'a: {x: 1,\n' ' y,\n' ' z: 1}\n', conf, problem=(3, 6) + ) + self.check('---\n' 'a: {x: 1,\n' ' y, z: 1}\n', conf, problem=(3, 3)) + self.check('---\n' 'a: {x: 1,\n' ' y, z: 1\n' '}\n', conf) + self.check('---\n' 'a: {x: 1,\n' ' y, z: 1\n' '}\n', conf, problem=(3, 3)) + self.check('---\n' 'a: [x,\n' ' y,\n' ' z]\n', conf) + self.check('---\n' 'a: [x,\n' ' y,\n' ' z]\n', conf, problem=(3, 4)) + self.check('---\n' 'a: [x,\n' ' y,\n' ' z]\n', conf, problem=(3, 6)) + self.check('---\n' 'a: [x,\n' ' y, z]\n', conf, problem=(3, 3)) + self.check('---\n' 'a: [x,\n' ' y, z\n' ']\n', conf) + self.check('---\n' 'a: [x,\n' ' y, z\n' ']\n', conf, problem=(3, 3)) def test_broken_flows(self): # flow: [ # ... # ] conf = 'indentation: {spaces: consistent}' - self.check('---\n' - 'a: {\n' - ' x: 1,\n' - ' y, z: 1\n' - '}\n', conf) - self.check('---\n' - 'a: {\n' - ' x: 1,\n' - ' y, z: 1}\n', conf) - self.check('---\n' - 'a: {\n' - ' x: 1,\n' - ' y, z: 1\n' - '}\n', conf, problem=(4, 3)) - self.check('---\n' - 'a: {\n' - ' x: 1,\n' - ' y, z: 1\n' - ' }\n', conf, problem=(5, 3)) - self.check('---\n' - 'a: [\n' - ' x,\n' - ' y, z\n' - ']\n', conf) - self.check('---\n' - 'a: [\n' - ' x,\n' - ' y, z]\n', conf) - self.check('---\n' - 'a: [\n' - ' x,\n' - ' y, z\n' - ']\n', conf, problem=(4, 3)) - self.check('---\n' - 'a: [\n' - ' x,\n' - ' y, z\n' - ' ]\n', conf, problem=(5, 3)) - 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)) - self.check('---\n' - 'top:\n' - ' rules: [\n' - ' 1, 2,\n' - ' ]\n', conf) - self.check('---\n' - 'top:\n' - ' rules: [\n' - ' 1, 2,\n' - ']\n' - ' rulez: [\n' - ' 1, 2,\n' - ' ]\n', conf, problem1=(5, 1), problem2=(8, 5)) - self.check('---\n' - 'top:\n' - ' rules:\n' - ' here: {\n' - ' foo: 1,\n' - ' bar: 2\n' - ' }\n', conf) - self.check('---\n' - 'top:\n' - ' rules:\n' - ' here: {\n' - ' foo: 1,\n' - ' bar: 2\n' - ' }\n' - ' there: {\n' - ' foo: 1,\n' - ' bar: 2\n' - ' }\n', conf, problem1=(7, 7), problem2=(11, 3)) + self.check('---\n' 'a: {\n' ' x: 1,\n' ' y, z: 1\n' '}\n', conf) + self.check('---\n' 'a: {\n' ' x: 1,\n' ' y, z: 1}\n', conf) + self.check( + '---\n' 'a: {\n' ' x: 1,\n' ' y, z: 1\n' '}\n', conf, problem=(4, 3) + ) + self.check( + '---\n' 'a: {\n' ' x: 1,\n' ' y, z: 1\n' ' }\n', conf, problem=(5, 3) + ) + self.check('---\n' 'a: [\n' ' x,\n' ' y, z\n' ']\n', conf) + self.check('---\n' 'a: [\n' ' x,\n' ' y, z]\n', conf) + self.check('---\n' 'a: [\n' ' x,\n' ' y, z\n' ']\n', conf, problem=(4, 3)) + self.check('---\n' 'a: [\n' ' x,\n' ' y, z\n' ' ]\n', conf, problem=(5, 3)) + 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), + ) + self.check('---\n' 'top:\n' ' rules: [\n' ' 1, 2,\n' ' ]\n', conf) + self.check( + '---\n' + 'top:\n' + ' rules: [\n' + ' 1, 2,\n' + ']\n' + ' rulez: [\n' + ' 1, 2,\n' + ' ]\n', + conf, + problem1=(5, 1), + problem2=(8, 5), + ) + self.check( + '---\n' + 'top:\n' + ' rules:\n' + ' here: {\n' + ' foo: 1,\n' + ' bar: 2\n' + ' }\n', + conf, + ) + self.check( + '---\n' + 'top:\n' + ' rules:\n' + ' here: {\n' + ' foo: 1,\n' + ' bar: 2\n' + ' }\n' + ' there: {\n' + ' foo: 1,\n' + ' bar: 2\n' + ' }\n', + conf, + problem1=(7, 7), + problem2=(11, 3), + ) conf = 'indentation: {spaces: 2}' - self.check('---\n' - 'a: {\n' - ' x: 1,\n' - ' y, z: 1\n' - '}\n', conf, problem=(3, 4)) - self.check('---\n' - 'a: [\n' - ' x,\n' - ' y, z\n' - ']\n', conf, problem=(3, 4)) + self.check( + '---\n' 'a: {\n' ' x: 1,\n' ' y, z: 1\n' '}\n', conf, problem=(3, 4) + ) + self.check('---\n' 'a: [\n' ' x,\n' ' y, z\n' ']\n', conf, problem=(3, 4)) def test_cleared_flows(self): # flow: @@ -1095,280 +1183,292 @@ def test_cleared_flows(self): # ... # ] conf = 'indentation: {spaces: consistent}' - self.check('---\n' - 'top:\n' - ' rules:\n' - ' {\n' - ' foo: 1,\n' - ' bar: 2\n' - ' }\n', conf) - self.check('---\n' - 'top:\n' - ' rules:\n' - ' {\n' - ' foo: 1,\n' - ' bar: 2\n' - ' }\n', conf, problem=(5, 8)) - self.check('---\n' - 'top:\n' - ' rules:\n' - ' {\n' - ' foo: 1,\n' - ' bar: 2\n' - ' }\n', conf, problem=(4, 4)) - self.check('---\n' - 'top:\n' - ' rules:\n' - ' {\n' - ' foo: 1,\n' - ' bar: 2\n' - ' }\n', conf, problem=(7, 4)) - self.check('---\n' - 'top:\n' - ' rules:\n' - ' {\n' - ' foo: 1,\n' - ' bar: 2\n' - ' }\n', conf, problem=(7, 6)) - self.check('---\n' - 'top:\n' - ' [\n' - ' a, b, c\n' - ' ]\n', conf) - self.check('---\n' - 'top:\n' - ' [\n' - ' a, b, c\n' - ' ]\n', conf, problem=(4, 6)) - self.check('---\n' - 'top:\n' - ' [\n' - ' a, b, c\n' - ' ]\n', conf, problem=(4, 6)) - self.check('---\n' - 'top:\n' - ' [\n' - ' a, b, c\n' - ' ]\n', conf, problem=(5, 4)) - self.check('---\n' - 'top:\n' - ' rules: [\n' - ' {\n' - ' foo: 1\n' - ' },\n' - ' {\n' - ' foo: 2,\n' - ' bar: [\n' - ' a, b, c\n' - ' ],\n' - ' },\n' - ' ]\n', conf) - self.check('---\n' - 'top:\n' - ' rules: [\n' - ' {\n' - ' foo: 1\n' - ' },\n' - ' {\n' - ' foo: 2,\n' - ' bar: [\n' - ' a, b, c\n' - ' ],\n' - ' },\n' - ']\n', conf, problem1=(5, 6), problem2=(6, 6), - problem3=(9, 9), problem4=(11, 7), problem5=(13, 1)) + self.check( + '---\n' + 'top:\n' + ' rules:\n' + ' {\n' + ' foo: 1,\n' + ' bar: 2\n' + ' }\n', + conf, + ) + self.check( + '---\n' + 'top:\n' + ' rules:\n' + ' {\n' + ' foo: 1,\n' + ' bar: 2\n' + ' }\n', + conf, + problem=(5, 8), + ) + self.check( + '---\n' + 'top:\n' + ' rules:\n' + ' {\n' + ' foo: 1,\n' + ' bar: 2\n' + ' }\n', + conf, + problem=(4, 4), + ) + self.check( + '---\n' + 'top:\n' + ' rules:\n' + ' {\n' + ' foo: 1,\n' + ' bar: 2\n' + ' }\n', + conf, + problem=(7, 4), + ) + self.check( + '---\n' + 'top:\n' + ' rules:\n' + ' {\n' + ' foo: 1,\n' + ' bar: 2\n' + ' }\n', + conf, + problem=(7, 6), + ) + self.check('---\n' 'top:\n' ' [\n' ' a, b, c\n' ' ]\n', conf) + self.check( + '---\n' 'top:\n' ' [\n' ' a, b, c\n' ' ]\n', conf, problem=(4, 6) + ) + self.check( + '---\n' 'top:\n' ' [\n' ' a, b, c\n' ' ]\n', conf, problem=(4, 6) + ) + self.check( + '---\n' 'top:\n' ' [\n' ' a, b, c\n' ' ]\n', conf, problem=(5, 4) + ) + self.check( + '---\n' + 'top:\n' + ' rules: [\n' + ' {\n' + ' foo: 1\n' + ' },\n' + ' {\n' + ' foo: 2,\n' + ' bar: [\n' + ' a, b, c\n' + ' ],\n' + ' },\n' + ' ]\n', + conf, + ) + self.check( + '---\n' + 'top:\n' + ' rules: [\n' + ' {\n' + ' foo: 1\n' + ' },\n' + ' {\n' + ' foo: 2,\n' + ' bar: [\n' + ' a, b, c\n' + ' ],\n' + ' },\n' + ']\n', + conf, + problem1=(5, 6), + problem2=(6, 6), + problem3=(9, 9), + problem4=(11, 7), + problem5=(13, 1), + ) def test_under_indented(self): conf = 'indentation: {spaces: 2, indent-sequences: consistent}' - self.check('---\n' - 'object:\n' - ' val: 1\n' - '...\n', conf, problem=(3, 2)) - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - '...\n', conf, problem=(4, 4)) - self.check('---\n' - 'object:\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - '...\n', conf, problem=(5, 6, 'syntax')) + self.check('---\n' 'object:\n' ' val: 1\n' '...\n', conf, problem=(3, 2)) + self.check( + '---\n' 'object:\n' ' k1:\n' ' - a\n' '...\n', conf, problem=(4, 4) + ) + self.check( + '---\n' + 'object:\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + '...\n', + conf, + problem=(5, 6, 'syntax'), + ) conf = 'indentation: {spaces: 4, indent-sequences: consistent}' - self.check('---\n' - 'object:\n' - ' val: 1\n' - '...\n', conf, problem=(3, 4)) - self.check('---\n' - '- el1\n' - '- el2:\n' - ' - subel\n' - '...\n', conf, problem=(4, 4)) - self.check('---\n' - 'object:\n' - ' k3:\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf, problem=(5, 10, 'syntax')) + self.check('---\n' 'object:\n' ' val: 1\n' '...\n', conf, problem=(3, 4)) + self.check( + '---\n' '- el1\n' '- el2:\n' ' - subel\n' '...\n', conf, problem=(4, 4) + ) + self.check( + '---\n' + 'object:\n' + ' k3:\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + problem=(5, 10, 'syntax'), + ) conf = 'indentation: {spaces: 2, indent-sequences: true}' - self.check('---\n' - 'a:\n' - '-\n' # empty list - 'b: c\n' - '...\n', conf, problem=(3, 1)) + self.check( + '---\n' + 'a:\n' + '-\n' # empty list + 'b: c\n' + '...\n', + conf, + problem=(3, 1), + ) conf = 'indentation: {spaces: 2, indent-sequences: consistent}' - self.check('---\n' - 'a:\n' - ' -\n' # empty list - 'b:\n' - '-\n' - 'c: d\n' - '...\n', conf, problem=(5, 1)) + self.check( + '---\n' + 'a:\n' + ' -\n' # empty list + 'b:\n' + '-\n' + 'c: d\n' + '...\n', + conf, + problem=(5, 1), + ) def test_over_indented(self): conf = 'indentation: {spaces: 2, indent-sequences: consistent}' - self.check('---\n' - 'object:\n' - ' val: 1\n' - '...\n', conf, problem=(3, 4)) - self.check('---\n' - 'object:\n' - ' k1:\n' - ' - a\n' - '...\n', conf, problem=(4, 6)) - self.check('---\n' - 'object:\n' - ' k3:\n' - ' - name: Unix\n' - ' date: 1969\n' - '...\n', conf, problem=(5, 12, 'syntax')) + self.check('---\n' 'object:\n' ' val: 1\n' '...\n', conf, problem=(3, 4)) + self.check( + '---\n' 'object:\n' ' k1:\n' ' - a\n' '...\n', conf, problem=(4, 6) + ) + self.check( + '---\n' + 'object:\n' + ' k3:\n' + ' - name: Unix\n' + ' date: 1969\n' + '...\n', + conf, + problem=(5, 12, 'syntax'), + ) conf = 'indentation: {spaces: 4, indent-sequences: consistent}' - self.check('---\n' - 'object:\n' - ' val: 1\n' - '...\n', conf, problem=(3, 6)) - self.check('---\n' - ' object:\n' - ' val: 1\n' - '...\n', conf, problem=(2, 2)) - self.check('---\n' - '- el1\n' - '- el2:\n' - ' - subel\n' - '...\n', conf, problem=(4, 6)) - self.check('---\n' - '- el1\n' - '- el2:\n' - ' - subel\n' - '...\n', conf, problem=(4, 15)) - self.check('---\n' - ' - el1\n' - ' - el2:\n' - ' - subel\n' - '...\n', conf, - problem=(2, 3)) - self.check('---\n' - 'object:\n' - ' k3:\n' - ' - name: Linux\n' - ' date: 1991\n' - '...\n', conf, problem=(5, 16, 'syntax')) + self.check('---\n' 'object:\n' ' val: 1\n' '...\n', conf, problem=(3, 6)) + self.check('---\n' ' object:\n' ' val: 1\n' '...\n', conf, problem=(2, 2)) + self.check( + '---\n' '- el1\n' '- el2:\n' ' - subel\n' '...\n', conf, problem=(4, 6) + ) + self.check( + '---\n' '- el1\n' '- el2:\n' ' - subel\n' '...\n', + conf, + problem=(4, 15), + ) + self.check( + '---\n' ' - el1\n' ' - el2:\n' ' - subel\n' '...\n', + conf, + problem=(2, 3), + ) + self.check( + '---\n' + 'object:\n' + ' k3:\n' + ' - name: Linux\n' + ' date: 1991\n' + '...\n', + conf, + problem=(5, 16, 'syntax'), + ) conf = 'indentation: {spaces: 4, indent-sequences: whatever}' - self.check('---\n' - ' - el1\n' - ' - el2:\n' - ' - subel\n' - '...\n', conf, - problem=(2, 3)) + self.check( + '---\n' ' - el1\n' ' - el2:\n' ' - subel\n' '...\n', + conf, + problem=(2, 3), + ) conf = 'indentation: {spaces: 2, indent-sequences: false}' - self.check('---\n' - 'a:\n' - ' -\n' # empty list - 'b: c\n' - '...\n', conf, problem=(3, 3)) + self.check( + '---\n' + 'a:\n' + ' -\n' # empty list + 'b: c\n' + '...\n', + conf, + problem=(3, 3), + ) conf = 'indentation: {spaces: 2, indent-sequences: consistent}' - self.check('---\n' - 'a:\n' - '-\n' # empty list - 'b:\n' - ' -\n' - 'c: d\n' - '...\n', conf, problem=(5, 3)) + self.check( + '---\n' + 'a:\n' + '-\n' # empty list + 'b:\n' + ' -\n' + 'c: d\n' + '...\n', + conf, + problem=(5, 3), + ) def test_multi_lines(self): conf = 'indentation: {spaces: consistent, indent-sequences: true}' - self.check('---\n' - 'long_string: >\n' - ' bla bla blah\n' - ' blah bla bla\n' - '...\n', conf) - self.check('---\n' - '- long_string: >\n' - ' bla bla blah\n' - ' blah bla bla\n' - '...\n', conf) - self.check('---\n' - 'obj:\n' - ' - long_string: >\n' - ' bla bla blah\n' - ' blah bla bla\n' - '...\n', conf) + self.check( + '---\n' 'long_string: >\n' ' bla bla blah\n' ' blah bla bla\n' '...\n', + conf, + ) + self.check( + '---\n' + '- long_string: >\n' + ' bla bla blah\n' + ' blah bla bla\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'obj:\n' + ' - long_string: >\n' + ' bla bla blah\n' + ' blah bla bla\n' + '...\n', + conf, + ) def test_empty_value(self): conf = 'indentation: {spaces: consistent}' - self.check('---\n' - 'key1:\n' - 'key2: not empty\n' - 'key3:\n' - '...\n', conf) - self.check('---\n' - '-\n' - '- item 2\n' - '-\n' - '...\n', conf) + self.check('---\n' 'key1:\n' 'key2: not empty\n' 'key3:\n' '...\n', conf) + self.check('---\n' '-\n' '- item 2\n' '-\n' '...\n', conf) 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, 'syntax')) - self.check('---\n' - '- o:\n' - ' k1: v1\n' - '...\n', conf, problem=(3, 4)) + self.check('---\n' '- o:\n' ' k1: v1\n' '...\n', conf) + self.check('---\n' '- o:\n' ' k1: v1\n' '...\n', conf, problem=(3, 2, 'syntax')) + self.check('---\n' '- o:\n' ' k1: v1\n' '...\n', conf, problem=(3, 4)) conf = 'indentation: {spaces: 4}' - self.check('---\n' - '- o:\n' - ' k1: v1\n' - '...\n', conf) - self.check('---\n' - '- o:\n' - ' k1: v1\n' - '...\n', conf, problem=(3, 6)) - self.check('---\n' - '- o:\n' - ' k1: v1\n' - '...\n', conf, problem=(3, 8)) - self.check('---\n' - '- - - - item\n' - ' - elem 1\n' - ' - elem 2\n' - ' - - - - - very nested: a\n' - ' key: value\n' - '...\n', conf) - self.check('---\n' - ' - - - - item\n' - ' - elem 1\n' - ' - elem 2\n' - ' - - - - - very nested: a\n' - ' key: value\n' - '...\n', conf, problem=(2, 2)) + self.check('---\n' '- o:\n' ' k1: v1\n' '...\n', conf) + self.check('---\n' '- o:\n' ' k1: v1\n' '...\n', conf, problem=(3, 6)) + self.check('---\n' '- o:\n' ' k1: v1\n' '...\n', conf, problem=(3, 8)) + self.check( + '---\n' + '- - - - item\n' + ' - elem 1\n' + ' - elem 2\n' + ' - - - - - very nested: a\n' + ' key: value\n' + '...\n', + conf, + ) + self.check( + '---\n' + ' - - - - item\n' + ' - elem 1\n' + ' - elem 2\n' + ' - - - - - very nested: a\n' + ' key: value\n' + '...\n', + conf, + problem=(2, 2), + ) def test_nested_collections_with_spaces_consistent(self): """Tests behavior of {spaces: consistent} in nested collections to @@ -1376,785 +1476,849 @@ def test_nested_collections_with_spaces_consistent(self): expected indent value is initially unknown. For details, see https://github.com/adrienverge/yamllint/issues/485. """ - conf = ('indentation: {spaces: consistent,\n' - ' indent-sequences: true}') - self.check('---\n' - '- item:\n' - ' - elem\n' - '- item:\n' - ' - elem\n' - '...\n', conf, problem=(3, 3)) - conf = ('indentation: {spaces: consistent,\n' - ' indent-sequences: false}') - self.check('---\n' - '- item:\n' - ' - elem\n' - '- item:\n' - ' - elem\n' - '...\n', conf, problem=(5, 5)) - conf = ('indentation: {spaces: consistent,\n' - ' indent-sequences: consistent}') - self.check('---\n' - '- item:\n' - ' - elem\n' - '- item:\n' - ' - elem\n' - '...\n', conf, problem=(5, 5)) - conf = ('indentation: {spaces: consistent,\n' - ' indent-sequences: whatever}') - self.check('---\n' - '- item:\n' - ' - elem\n' - '- item:\n' - ' - elem\n' - '...\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' indent-sequences: true}' + ) + self.check( + '---\n' '- item:\n' ' - elem\n' '- item:\n' ' - elem\n' '...\n', + conf, + problem=(3, 3), + ) + conf = ( + 'indentation: {spaces: consistent,\n' + ' indent-sequences: false}' + ) + self.check( + '---\n' '- item:\n' ' - elem\n' '- item:\n' ' - elem\n' '...\n', + conf, + problem=(5, 5), + ) + conf = ( + 'indentation: {spaces: consistent,\n' + ' indent-sequences: consistent}' + ) + self.check( + '---\n' '- item:\n' ' - elem\n' '- item:\n' ' - elem\n' '...\n', + conf, + problem=(5, 5), + ) + conf = ( + 'indentation: {spaces: consistent,\n' + ' indent-sequences: whatever}' + ) + self.check( + '---\n' '- item:\n' ' - elem\n' '- item:\n' ' - elem\n' '...\n', conf + ) def test_return(self): conf = 'indentation: {spaces: consistent}' - self.check('---\n' - 'a:\n' - ' b:\n' - ' c:\n' - ' d:\n' - ' e:\n' - ' f:\n' - 'g:\n' - '...\n', conf) - self.check('---\n' - 'a:\n' - ' b:\n' - ' c:\n' - ' d:\n' - '...\n', conf, problem=(5, 4, 'syntax')) - self.check('---\n' - 'a:\n' - ' b:\n' - ' c:\n' - ' d:\n' - '...\n', conf, problem=(5, 2, 'syntax')) + self.check( + '---\n' + 'a:\n' + ' b:\n' + ' c:\n' + ' d:\n' + ' e:\n' + ' f:\n' + 'g:\n' + '...\n', + conf, + ) + self.check( + '---\n' 'a:\n' ' b:\n' ' c:\n' ' d:\n' '...\n', + conf, + problem=(5, 4, 'syntax'), + ) + self.check( + '---\n' 'a:\n' ' b:\n' ' c:\n' ' d:\n' '...\n', + conf, + problem=(5, 2, 'syntax'), + ) def test_first_line(self): - conf = ('indentation: {spaces: consistent}\n' - 'document-start: disable\n') + conf = 'indentation: {spaces: consistent}\n' 'document-start: disable\n' self.check(' a: 1\n', conf, problem=(1, 3)) def test_explicit_block_mappings(self): conf = 'indentation: {spaces: consistent}' - self.check('---\n' - 'object:\n' - ' ? key\n' - ' : value\n', conf) - self.check('---\n' - 'object:\n' - ' ? key\n' - ' :\n' - ' value\n' - '...\n', conf) - self.check('---\n' - 'object:\n' - ' ?\n' - ' key\n' - ' : value\n', conf) - self.check('---\n' - 'object:\n' - ' ?\n' - ' key\n' - ' :\n' - ' value\n' - '...\n', conf) - self.check('---\n' - '- ? key\n' - ' : value\n', conf) - self.check('---\n' - '- ? key\n' - ' :\n' - ' value\n' - '...\n', conf) - self.check('---\n' - '- ?\n' - ' key\n' - ' : value\n', conf) - self.check('---\n' - '- ?\n' - ' key\n' - ' :\n' - ' value\n' - '...\n', conf) - self.check('---\n' - 'object:\n' - ' ? key\n' - ' :\n' - ' value\n' - '...\n', conf, problem=(5, 8)) - self.check('---\n' - '- - ?\n' - ' key\n' - ' :\n' - ' value\n' - '...\n', conf, problem=(5, 7)) - self.check('---\n' - 'object:\n' - ' ?\n' - ' key\n' - ' :\n' - ' value\n' - '...\n', conf, problem1=(4, 8), problem2=(6, 10)) - self.check('---\n' - 'object:\n' - ' ?\n' - ' key\n' - ' :\n' - ' value\n' - '...\n', conf, problem1=(4, 10), problem2=(6, 8)) + self.check('---\n' 'object:\n' ' ? key\n' ' : value\n', conf) + self.check( + '---\n' 'object:\n' ' ? key\n' ' :\n' ' value\n' '...\n', conf + ) + self.check('---\n' 'object:\n' ' ?\n' ' key\n' ' : value\n', conf) + self.check( + '---\n' + 'object:\n' + ' ?\n' + ' key\n' + ' :\n' + ' value\n' + '...\n', + conf, + ) + self.check('---\n' '- ? key\n' ' : value\n', conf) + self.check('---\n' '- ? key\n' ' :\n' ' value\n' '...\n', conf) + self.check('---\n' '- ?\n' ' key\n' ' : value\n', conf) + self.check('---\n' '- ?\n' ' key\n' ' :\n' ' value\n' '...\n', conf) + self.check( + '---\n' 'object:\n' ' ? key\n' ' :\n' ' value\n' '...\n', + conf, + problem=(5, 8), + ) + self.check( + '---\n' '- - ?\n' ' key\n' ' :\n' ' value\n' '...\n', + conf, + problem=(5, 7), + ) + self.check( + '---\n' + 'object:\n' + ' ?\n' + ' key\n' + ' :\n' + ' value\n' + '...\n', + conf, + problem1=(4, 8), + problem2=(6, 10), + ) + self.check( + '---\n' + 'object:\n' + ' ?\n' + ' key\n' + ' :\n' + ' value\n' + '...\n', + conf, + problem1=(4, 10), + problem2=(6, 8), + ) def test_clear_sequence_item(self): conf = 'indentation: {spaces: consistent}' - self.check('---\n' - '-\n' - ' string\n' - '-\n' - ' map: ping\n' - '-\n' - ' - sequence\n' - ' -\n' - ' nested\n' - ' -\n' - ' >\n' - ' multi\n' - ' line\n' - '...\n', conf) - self.check('---\n' - '-\n' - ' string\n' - '-\n' - ' string\n', conf, problem=(5, 4)) - self.check('---\n' - '-\n' - ' map: ping\n' - '-\n' - ' map: ping\n', conf, problem=(5, 4)) - self.check('---\n' - '-\n' - ' - sequence\n' - '-\n' - ' - sequence\n', conf, problem=(5, 4)) - self.check('---\n' - '-\n' - ' -\n' - ' nested\n' - ' -\n' - ' nested\n', conf, problem1=(4, 4), problem2=(6, 6)) - self.check('---\n' - '-\n' - ' -\n' - ' >\n' - ' multi\n' - ' line\n' - '...\n', conf, problem=(4, 6)) + self.check( + '---\n' + '-\n' + ' string\n' + '-\n' + ' map: ping\n' + '-\n' + ' - sequence\n' + ' -\n' + ' nested\n' + ' -\n' + ' >\n' + ' multi\n' + ' line\n' + '...\n', + conf, + ) + self.check('---\n' '-\n' ' string\n' '-\n' ' string\n', conf, problem=(5, 4)) + self.check( + '---\n' '-\n' ' map: ping\n' '-\n' ' map: ping\n', conf, problem=(5, 4) + ) + self.check( + '---\n' '-\n' ' - sequence\n' '-\n' ' - sequence\n', conf, problem=(5, 4) + ) + self.check( + '---\n' '-\n' ' -\n' ' nested\n' ' -\n' ' nested\n', + conf, + problem1=(4, 4), + problem2=(6, 6), + ) + self.check( + '---\n' '-\n' ' -\n' ' >\n' ' multi\n' ' line\n' '...\n', + conf, + problem=(4, 6), + ) conf = 'indentation: {spaces: 2}' - self.check('---\n' - '-\n' - ' string\n' - '-\n' - ' string\n', conf, problem1=(3, 2), problem2=(5, 4)) - self.check('---\n' - '-\n' - ' map: ping\n' - '-\n' - ' map: ping\n', conf, problem1=(3, 2), problem2=(5, 4)) - self.check('---\n' - '-\n' - ' - sequence\n' - '-\n' - ' - sequence\n', conf, problem1=(3, 2), problem2=(5, 4)) - self.check('---\n' - '-\n' - ' -\n' - ' nested\n' - ' -\n' - ' nested\n', conf, problem1=(4, 4), problem2=(6, 6)) + self.check( + '---\n' '-\n' ' string\n' '-\n' ' string\n', + conf, + problem1=(3, 2), + problem2=(5, 4), + ) + self.check( + '---\n' '-\n' ' map: ping\n' '-\n' ' map: ping\n', + conf, + problem1=(3, 2), + problem2=(5, 4), + ) + self.check( + '---\n' '-\n' ' - sequence\n' '-\n' ' - sequence\n', + conf, + problem1=(3, 2), + problem2=(5, 4), + ) + self.check( + '---\n' '-\n' ' -\n' ' nested\n' ' -\n' ' nested\n', + conf, + problem1=(4, 4), + problem2=(6, 6), + ) def test_anchors(self): conf = 'indentation: {spaces: consistent}' - self.check('---\n' - 'key: &anchor value\n', conf) - self.check('---\n' - 'key: &anchor\n' - ' value\n', conf) - self.check('---\n' - '- &anchor value\n', conf) - self.check('---\n' - '- &anchor\n' - ' value\n', conf) - self.check('---\n' - 'key: &anchor [1,\n' - ' 2]\n', conf) - self.check('---\n' - 'key: &anchor\n' - ' [1,\n' - ' 2]\n', conf) - self.check('---\n' - 'key: &anchor\n' - ' - 1\n' - ' - 2\n', conf) - self.check('---\n' - '- &anchor [1,\n' - ' 2]\n', conf) - self.check('---\n' - '- &anchor\n' - ' [1,\n' - ' 2]\n', conf) - self.check('---\n' - '- &anchor\n' - ' - 1\n' - ' - 2\n', conf) - self.check('---\n' - 'key:\n' - ' &anchor1\n' - ' value\n', conf) - self.check('---\n' - 'pre:\n' - ' &anchor1 0\n' - '&anchor2 key:\n' - ' value\n', conf) - self.check('---\n' - 'machine0:\n' - ' /etc/hosts: &ref-etc-hosts\n' - ' content:\n' - ' - 127.0.0.1: localhost\n' - ' - ::1: localhost\n' - ' mode: 0644\n' - 'machine1:\n' - ' /etc/hosts: *ref-etc-hosts\n', conf) - self.check('---\n' - 'list:\n' - ' - k: v\n' - ' - &a truc\n' - ' - &b\n' - ' truc\n' - ' - k: *a\n', conf) + self.check('---\n' 'key: &anchor value\n', conf) + self.check('---\n' 'key: &anchor\n' ' value\n', conf) + self.check('---\n' '- &anchor value\n', conf) + self.check('---\n' '- &anchor\n' ' value\n', conf) + self.check('---\n' 'key: &anchor [1,\n' ' 2]\n', conf) + self.check('---\n' 'key: &anchor\n' ' [1,\n' ' 2]\n', conf) + self.check('---\n' 'key: &anchor\n' ' - 1\n' ' - 2\n', conf) + self.check('---\n' '- &anchor [1,\n' ' 2]\n', conf) + self.check('---\n' '- &anchor\n' ' [1,\n' ' 2]\n', conf) + self.check('---\n' '- &anchor\n' ' - 1\n' ' - 2\n', conf) + self.check('---\n' 'key:\n' ' &anchor1\n' ' value\n', conf) + self.check( + '---\n' 'pre:\n' ' &anchor1 0\n' '&anchor2 key:\n' ' value\n', conf + ) + self.check( + '---\n' + 'machine0:\n' + ' /etc/hosts: &ref-etc-hosts\n' + ' content:\n' + ' - 127.0.0.1: localhost\n' + ' - ::1: localhost\n' + ' mode: 0644\n' + 'machine1:\n' + ' /etc/hosts: *ref-etc-hosts\n', + conf, + ) + self.check( + '---\n' + 'list:\n' + ' - k: v\n' + ' - &a truc\n' + ' - &b\n' + ' truc\n' + ' - k: *a\n', + conf, + ) def test_tags(self): conf = 'indentation: {spaces: consistent}' - self.check('---\n' - '-\n' - ' "flow in block"\n' - '- >\n' - ' Block scalar\n' - '- !!map # Block collection\n' - ' foo: bar\n', conf) + self.check( + '---\n' + '-\n' + ' "flow in block"\n' + '- >\n' + ' Block scalar\n' + '- !!map # Block collection\n' + ' foo: bar\n', + conf, + ) conf = 'indentation: {spaces: consistent, indent-sequences: false}' - self.check('---\n' - 'sequence: !!seq\n' - '- entry\n' - '- !!seq\n' - ' - nested\n', conf) - self.check('---\n' - 'mapping: !!map\n' - ' foo: bar\n' - 'Block style: !!map\n' - ' Clark: Evans\n' - ' Ingy: döt Net\n' - ' Oren: Ben-Kiki\n', conf) - self.check('---\n' - 'Flow style: !!map {Clark: Evans, Ingy: döt Net}\n' - 'Block style: !!seq\n' - '- Clark Evans\n' - '- Ingy döt Net\n', conf) + self.check( + '---\n' 'sequence: !!seq\n' '- entry\n' '- !!seq\n' ' - nested\n', conf + ) + self.check( + '---\n' + 'mapping: !!map\n' + ' foo: bar\n' + 'Block style: !!map\n' + ' Clark: Evans\n' + ' Ingy: döt Net\n' + ' Oren: Ben-Kiki\n', + conf, + ) + self.check( + '---\n' + 'Flow style: !!map {Clark: Evans, Ingy: döt Net}\n' + 'Block style: !!seq\n' + '- Clark Evans\n' + '- Ingy döt Net\n', + conf, + ) def test_flows_imbrication(self): conf = 'indentation: {spaces: consistent}' - self.check('---\n' - '[val]: value\n', conf) - self.check('---\n' - '{key}: value\n', conf) - self.check('---\n' - '{key: val}: value\n', conf) - self.check('---\n' - '[[val]]: value\n', conf) - self.check('---\n' - '{{key}}: value\n', conf) - self.check('---\n' - '{{key: val1}: val2}: value\n', conf) - self.check('---\n' - '- [val, {{key: val}: val}]: value\n' - '- {[val,\n' - ' {{key: val}: val}]}\n' - '- {[val,\n' - ' {{key: val,\n' - ' key2}}]}\n' - '- {{{{{moustaches}}}}}\n' - '- {{{{{moustache,\n' - ' moustache},\n' - ' moustache}},\n' - ' moustache}}\n', conf) - self.check('---\n' - '- {[val,\n' - ' {{key: val}: val}]}\n', - conf, problem=(3, 6)) - self.check('---\n' - '- {[val,\n' - ' {{key: val,\n' - ' key2}}]}\n', - conf, problem=(4, 6)) - self.check('---\n' - '- {{{{{moustache,\n' - ' moustache},\n' - ' moustache}},\n' - ' moustache}}\n', - conf, problem1=(4, 8), problem2=(5, 4)) + self.check('---\n' '[val]: value\n', conf) + self.check('---\n' '{key}: value\n', conf) + self.check('---\n' '{key: val}: value\n', conf) + self.check('---\n' '[[val]]: value\n', conf) + self.check('---\n' '{{key}}: value\n', conf) + self.check('---\n' '{{key: val1}: val2}: value\n', conf) + self.check( + '---\n' + '- [val, {{key: val}: val}]: value\n' + '- {[val,\n' + ' {{key: val}: val}]}\n' + '- {[val,\n' + ' {{key: val,\n' + ' key2}}]}\n' + '- {{{{{moustaches}}}}}\n' + '- {{{{{moustache,\n' + ' moustache},\n' + ' moustache}},\n' + ' moustache}}\n', + conf, + ) + self.check( + '---\n' '- {[val,\n' ' {{key: val}: val}]}\n', conf, problem=(3, 6) + ) + self.check( + '---\n' '- {[val,\n' ' {{key: val,\n' ' key2}}]}\n', + conf, + problem=(4, 6), + ) + self.check( + '---\n' + '- {{{{{moustache,\n' + ' moustache},\n' + ' moustache}},\n' + ' moustache}}\n', + conf, + problem1=(4, 8), + problem2=(5, 4), + ) class ScalarIndentationTestCase(RuleTestCase): rule_id = 'indentation' def test_basics_plain(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: false}\n' - 'document-start: disable\n') - self.check('multi\n' - 'line\n', conf) - self.check('multi\n' - ' line\n', conf) - self.check('- multi\n' - ' line\n', conf) - self.check('- multi\n' - ' line\n', conf) - self.check('a key: multi\n' - ' line\n', conf) - self.check('a key: multi\n' - ' line\n', conf) - self.check('a key: multi\n' - ' line\n', conf) - self.check('a key:\n' - ' multi\n' - ' line\n', conf) - self.check('- C code: void main() {\n' - ' printf("foo");\n' - ' }\n', conf) - self.check('- C code:\n' - ' void main() {\n' - ' printf("foo");\n' - ' }\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: false}\n' + 'document-start: disable\n' + ) + self.check('multi\n' 'line\n', conf) + self.check('multi\n' ' line\n', conf) + self.check('- multi\n' ' line\n', conf) + self.check('- multi\n' ' line\n', conf) + self.check('a key: multi\n' ' line\n', conf) + self.check('a key: multi\n' ' line\n', conf) + self.check('a key: multi\n' ' line\n', conf) + self.check('a key:\n' ' multi\n' ' line\n', conf) + self.check( + '- C code: void main() {\n' + ' printf("foo");\n' + ' }\n', + conf, + ) + self.check( + '- C code:\n' ' void main() {\n' ' printf("foo");\n' ' }\n', + conf, + ) def test_check_multi_line_plain(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('multi\n' - ' line\n', conf, problem=(2, 2)) - self.check('- multi\n' - ' line\n', conf, problem=(2, 4)) - self.check('a key: multi\n' - ' line\n', conf, problem=(2, 3)) - self.check('a key: multi\n' - ' line\n', conf, problem=(2, 9)) - self.check('a key:\n' - ' multi\n' - ' line\n', conf, problem=(3, 4)) - self.check('- C code: void main() {\n' - ' printf("foo");\n' - ' }\n', conf, problem=(2, 15)) - self.check('- C code:\n' - ' void main() {\n' - ' printf("foo");\n' - ' }\n', conf, problem=(3, 9)) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check('multi\n' ' line\n', conf, problem=(2, 2)) + self.check('- multi\n' ' line\n', conf, problem=(2, 4)) + self.check('a key: multi\n' ' line\n', conf, problem=(2, 3)) + self.check('a key: multi\n' ' line\n', conf, problem=(2, 9)) + self.check('a key:\n' ' multi\n' ' line\n', conf, problem=(3, 4)) + self.check( + '- C code: void main() {\n' + ' printf("foo");\n' + ' }\n', + conf, + problem=(2, 15), + ) + self.check( + '- C code:\n' ' void main() {\n' ' printf("foo");\n' ' }\n', + conf, + problem=(3, 9), + ) def test_basics_quoted(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: false}\n' - 'document-start: disable\n') - self.check('"multi\n' - ' line"\n', conf) - self.check('- "multi\n' - ' line"\n', conf) - self.check('a key: "multi\n' - ' line"\n', conf) - self.check('a key:\n' - ' "multi\n' - ' line"\n', conf) - self.check('- jinja2: "{% if ansible is defined %}\n' - ' {{ ansible }}\n' - ' {% else %}\n' - ' {{ chef }}\n' - ' {% endif %}"\n', conf) - self.check('- jinja2:\n' - ' "{% if ansible is defined %}\n' - ' {{ ansible }}\n' - ' {% else %}\n' - ' {{ chef }}\n' - ' {% endif %}"\n', conf) - self.check('["this is a very long line\n' - ' that needs to be split",\n' - ' "other line"]\n', conf) - self.check('["multi\n' - ' line 1", "multi\n' - ' line 2"]\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: false}\n' + 'document-start: disable\n' + ) + self.check('"multi\n' ' line"\n', conf) + self.check('- "multi\n' ' line"\n', conf) + self.check('a key: "multi\n' ' line"\n', conf) + self.check('a key:\n' ' "multi\n' ' line"\n', conf) + self.check( + '- jinja2: "{% if ansible is defined %}\n' + ' {{ ansible }}\n' + ' {% else %}\n' + ' {{ chef }}\n' + ' {% endif %}"\n', + conf, + ) + self.check( + '- jinja2:\n' + ' "{% if ansible is defined %}\n' + ' {{ ansible }}\n' + ' {% else %}\n' + ' {{ chef }}\n' + ' {% endif %}"\n', + conf, + ) + self.check( + '["this is a very long line\n' + ' that needs to be split",\n' + ' "other line"]\n', + conf, + ) + self.check('["multi\n' ' line 1", "multi\n' ' line 2"]\n', conf) def test_check_multi_line_quoted(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('"multi\n' - 'line"\n', conf, problem=(2, 1)) - self.check('"multi\n' - ' line"\n', conf, problem=(2, 3)) - self.check('- "multi\n' - ' line"\n', conf, problem=(2, 3)) - self.check('- "multi\n' - ' line"\n', conf, problem=(2, 5)) - self.check('a key: "multi\n' - ' line"\n', conf, problem=(2, 3)) - self.check('a key: "multi\n' - ' line"\n', conf, problem=(2, 8)) - self.check('a key: "multi\n' - ' line"\n', conf, problem=(2, 10)) - self.check('a key:\n' - ' "multi\n' - ' line"\n', conf, problem=(3, 3)) - self.check('a key:\n' - ' "multi\n' - ' line"\n', conf, problem=(3, 5)) - self.check('- jinja2: "{% if ansible is defined %}\n' - ' {{ ansible }}\n' - ' {% else %}\n' - ' {{ chef }}\n' - ' {% endif %}"\n', conf, - problem1=(2, 14), problem2=(4, 14)) - self.check('- jinja2:\n' - ' "{% if ansible is defined %}\n' - ' {{ ansible }}\n' - ' {% else %}\n' - ' {{ chef }}\n' - ' {% endif %}"\n', conf, - problem1=(3, 8), problem2=(5, 8)) - self.check('["this is a very long line\n' - ' that needs to be split",\n' - ' "other line"]\n', conf) - self.check('["this is a very long line\n' - ' that needs to be split",\n' - ' "other line"]\n', conf, problem=(2, 2)) - self.check('["this is a very long line\n' - ' that needs to be split",\n' - ' "other line"]\n', conf, problem=(2, 4)) - self.check('["multi\n' - ' line 1", "multi\n' - ' line 2"]\n', conf) - self.check('["multi\n' - ' line 1", "multi\n' - ' line 2"]\n', conf, problem=(3, 12)) - self.check('["multi\n' - ' line 1", "multi\n' - ' line 2"]\n', conf, problem=(3, 14)) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check('"multi\n' 'line"\n', conf, problem=(2, 1)) + self.check('"multi\n' ' line"\n', conf, problem=(2, 3)) + self.check('- "multi\n' ' line"\n', conf, problem=(2, 3)) + self.check('- "multi\n' ' line"\n', conf, problem=(2, 5)) + self.check('a key: "multi\n' ' line"\n', conf, problem=(2, 3)) + self.check('a key: "multi\n' ' line"\n', conf, problem=(2, 8)) + self.check('a key: "multi\n' ' line"\n', conf, problem=(2, 10)) + self.check('a key:\n' ' "multi\n' ' line"\n', conf, problem=(3, 3)) + self.check('a key:\n' ' "multi\n' ' line"\n', conf, problem=(3, 5)) + self.check( + '- jinja2: "{% if ansible is defined %}\n' + ' {{ ansible }}\n' + ' {% else %}\n' + ' {{ chef }}\n' + ' {% endif %}"\n', + conf, + problem1=(2, 14), + problem2=(4, 14), + ) + self.check( + '- jinja2:\n' + ' "{% if ansible is defined %}\n' + ' {{ ansible }}\n' + ' {% else %}\n' + ' {{ chef }}\n' + ' {% endif %}"\n', + conf, + problem1=(3, 8), + problem2=(5, 8), + ) + self.check( + '["this is a very long line\n' + ' that needs to be split",\n' + ' "other line"]\n', + conf, + ) + self.check( + '["this is a very long line\n' + ' that needs to be split",\n' + ' "other line"]\n', + conf, + problem=(2, 2), + ) + self.check( + '["this is a very long line\n' + ' that needs to be split",\n' + ' "other line"]\n', + conf, + problem=(2, 4), + ) + self.check('["multi\n' ' line 1", "multi\n' ' line 2"]\n', conf) + self.check( + '["multi\n' ' line 1", "multi\n' ' line 2"]\n', + conf, + problem=(3, 12), + ) + self.check( + '["multi\n' ' line 1", "multi\n' ' line 2"]\n', + conf, + problem=(3, 14), + ) def test_basics_folded_style(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: false}\n' - 'document-start: disable\n') - self.check('>\n' - ' multi\n' - ' line\n', conf) - self.check('- >\n' - ' multi\n' - ' line\n', conf) - self.check('- key: >\n' - ' multi\n' - ' line\n', conf) - self.check('- key:\n' - ' >\n' - ' multi\n' - ' line\n', conf) - self.check('- ? >\n' - ' multi-line\n' - ' key\n' - ' : >\n' - ' multi-line\n' - ' value\n', conf) - self.check('- ?\n' - ' >\n' - ' multi-line\n' - ' key\n' - ' :\n' - ' >\n' - ' multi-line\n' - ' value\n', conf) - self.check('- jinja2: >\n' - ' {% if ansible is defined %}\n' - ' {{ ansible }}\n' - ' {% else %}\n' - ' {{ chef }}\n' - ' {% endif %}\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: false}\n' + 'document-start: disable\n' + ) + self.check('>\n' ' multi\n' ' line\n', conf) + self.check('- >\n' ' multi\n' ' line\n', conf) + self.check('- key: >\n' ' multi\n' ' line\n', conf) + self.check('- key:\n' ' >\n' ' multi\n' ' line\n', conf) + self.check( + '- ? >\n' + ' multi-line\n' + ' key\n' + ' : >\n' + ' multi-line\n' + ' value\n', + conf, + ) + self.check( + '- ?\n' + ' >\n' + ' multi-line\n' + ' key\n' + ' :\n' + ' >\n' + ' multi-line\n' + ' value\n', + conf, + ) + self.check( + '- jinja2: >\n' + ' {% if ansible is defined %}\n' + ' {{ ansible }}\n' + ' {% else %}\n' + ' {{ chef }}\n' + ' {% endif %}\n', + conf, + ) def test_check_multi_line_folded_style(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('>\n' - ' multi\n' - ' line\n', conf, problem=(3, 4)) - self.check('- >\n' - ' multi\n' - ' line\n', conf, problem=(3, 6)) - self.check('- key: >\n' - ' multi\n' - ' line\n', conf, problem=(3, 6)) - self.check('- key:\n' - ' >\n' - ' multi\n' - ' line\n', conf, problem=(4, 8)) - self.check('- ? >\n' - ' multi-line\n' - ' key\n' - ' : >\n' - ' multi-line\n' - ' value\n', conf, - problem1=(3, 8), problem2=(6, 8)) - self.check('- ?\n' - ' >\n' - ' multi-line\n' - ' key\n' - ' :\n' - ' >\n' - ' multi-line\n' - ' value\n', conf, - problem1=(4, 8), problem2=(8, 8)) - self.check('- jinja2: >\n' - ' {% if ansible is defined %}\n' - ' {{ ansible }}\n' - ' {% else %}\n' - ' {{ chef }}\n' - ' {% endif %}\n', conf, - problem1=(3, 7), problem2=(5, 7)) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check('>\n' ' multi\n' ' line\n', conf, problem=(3, 4)) + self.check('- >\n' ' multi\n' ' line\n', conf, problem=(3, 6)) + self.check('- key: >\n' ' multi\n' ' line\n', conf, problem=(3, 6)) + self.check( + '- key:\n' ' >\n' ' multi\n' ' line\n', conf, problem=(4, 8) + ) + self.check( + '- ? >\n' + ' multi-line\n' + ' key\n' + ' : >\n' + ' multi-line\n' + ' value\n', + conf, + problem1=(3, 8), + problem2=(6, 8), + ) + self.check( + '- ?\n' + ' >\n' + ' multi-line\n' + ' key\n' + ' :\n' + ' >\n' + ' multi-line\n' + ' value\n', + conf, + problem1=(4, 8), + problem2=(8, 8), + ) + self.check( + '- jinja2: >\n' + ' {% if ansible is defined %}\n' + ' {{ ansible }}\n' + ' {% else %}\n' + ' {{ chef }}\n' + ' {% endif %}\n', + conf, + problem1=(3, 7), + problem2=(5, 7), + ) def test_basics_literal_style(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: false}\n' - 'document-start: disable\n') - self.check('|\n' - ' multi\n' - ' line\n', conf) - self.check('- |\n' - ' multi\n' - ' line\n', conf) - self.check('- key: |\n' - ' multi\n' - ' line\n', conf) - self.check('- key:\n' - ' |\n' - ' multi\n' - ' line\n', conf) - self.check('- ? |\n' - ' multi-line\n' - ' key\n' - ' : |\n' - ' multi-line\n' - ' value\n', conf) - self.check('- ?\n' - ' |\n' - ' multi-line\n' - ' key\n' - ' :\n' - ' |\n' - ' multi-line\n' - ' value\n', conf) - self.check('- jinja2: |\n' - ' {% if ansible is defined %}\n' - ' {{ ansible }}\n' - ' {% else %}\n' - ' {{ chef }}\n' - ' {% endif %}\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: false}\n' + 'document-start: disable\n' + ) + self.check('|\n' ' multi\n' ' line\n', conf) + self.check('- |\n' ' multi\n' ' line\n', conf) + self.check('- key: |\n' ' multi\n' ' line\n', conf) + self.check('- key:\n' ' |\n' ' multi\n' ' line\n', conf) + self.check( + '- ? |\n' + ' multi-line\n' + ' key\n' + ' : |\n' + ' multi-line\n' + ' value\n', + conf, + ) + self.check( + '- ?\n' + ' |\n' + ' multi-line\n' + ' key\n' + ' :\n' + ' |\n' + ' multi-line\n' + ' value\n', + conf, + ) + self.check( + '- jinja2: |\n' + ' {% if ansible is defined %}\n' + ' {{ ansible }}\n' + ' {% else %}\n' + ' {{ chef }}\n' + ' {% endif %}\n', + conf, + ) def test_check_multi_line_literal_style(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('|\n' - ' multi\n' - ' line\n', conf, problem=(3, 4)) - self.check('- |\n' - ' multi\n' - ' line\n', conf, problem=(3, 6)) - self.check('- key: |\n' - ' multi\n' - ' line\n', conf, problem=(3, 6)) - self.check('- key:\n' - ' |\n' - ' multi\n' - ' line\n', conf, problem=(4, 8)) - self.check('- ? |\n' - ' multi-line\n' - ' key\n' - ' : |\n' - ' multi-line\n' - ' value\n', conf, - problem1=(3, 8), problem2=(6, 8)) - self.check('- ?\n' - ' |\n' - ' multi-line\n' - ' key\n' - ' :\n' - ' |\n' - ' multi-line\n' - ' value\n', conf, - problem1=(4, 8), problem2=(8, 8)) - self.check('- jinja2: |\n' - ' {% if ansible is defined %}\n' - ' {{ ansible }}\n' - ' {% else %}\n' - ' {{ chef }}\n' - ' {% endif %}\n', conf, - problem1=(3, 7), problem2=(5, 7)) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check('|\n' ' multi\n' ' line\n', conf, problem=(3, 4)) + self.check('- |\n' ' multi\n' ' line\n', conf, problem=(3, 6)) + self.check('- key: |\n' ' multi\n' ' line\n', conf, problem=(3, 6)) + self.check( + '- key:\n' ' |\n' ' multi\n' ' line\n', conf, problem=(4, 8) + ) + self.check( + '- ? |\n' + ' multi-line\n' + ' key\n' + ' : |\n' + ' multi-line\n' + ' value\n', + conf, + problem1=(3, 8), + problem2=(6, 8), + ) + self.check( + '- ?\n' + ' |\n' + ' multi-line\n' + ' key\n' + ' :\n' + ' |\n' + ' multi-line\n' + ' value\n', + conf, + problem1=(4, 8), + problem2=(8, 8), + ) + self.check( + '- jinja2: |\n' + ' {% if ansible is defined %}\n' + ' {{ ansible }}\n' + ' {% else %}\n' + ' {{ chef }}\n' + ' {% endif %}\n', + conf, + problem1=(3, 7), + problem2=(5, 7), + ) # The following "paragraph" examples are inspired from # http://stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines def test_paragraph_plain(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('- long text: very "long"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\n', conf) - self.check('- long text: very "long"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\n', conf, - problem1=(2, 5), problem2=(4, 5), problem3=(5, 5)) - self.check('- long text:\n' - ' very "long"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check( + '- long text: very "long"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces.\n', + conf, + ) + self.check( + '- long text: very "long"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces.\n', + conf, + problem1=(2, 5), + problem2=(4, 5), + problem3=(5, 5), + ) + self.check( + '- long text:\n' + ' very "long"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces.\n', + conf, + ) def test_paragraph_double_quoted(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('- long text: "very \\"long\\"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces."\n', conf) - self.check('- long text: "very \\"long\\"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces."\n', conf, - problem1=(2, 5), problem2=(4, 5), problem3=(5, 5)) - self.check('- long text: "very \\"long\\"\n' - '\'string\' with\n' - '\n' - 'paragraph gap, \\n and\n' - 'spaces."\n', conf, - problem1=(2, 1), problem2=(4, 1), problem3=(5, 1)) - self.check('- long text:\n' - ' "very \\"long\\"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces."\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check( + '- long text: "very \\"long\\"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces."\n', + conf, + ) + self.check( + '- long text: "very \\"long\\"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces."\n', + conf, + problem1=(2, 5), + problem2=(4, 5), + problem3=(5, 5), + ) + self.check( + '- long text: "very \\"long\\"\n' + "'string' with\n" + '\n' + 'paragraph gap, \\n and\n' + 'spaces."\n', + conf, + problem1=(2, 1), + problem2=(4, 1), + problem3=(5, 1), + ) + self.check( + '- long text:\n' + ' "very \\"long\\"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces."\n', + conf, + ) def test_paragraph_single_quoted(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('- long text: \'very "long"\n' - ' \'\'string\'\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\'\n', conf) - self.check('- long text: \'very "long"\n' - ' \'\'string\'\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\'\n', conf, - problem1=(2, 5), problem2=(4, 5), problem3=(5, 5)) - self.check('- long text: \'very "long"\n' - '\'\'string\'\' with\n' - '\n' - 'paragraph gap, \\n and\n' - 'spaces.\'\n', conf, - problem1=(2, 1), problem2=(4, 1), problem3=(5, 1)) - self.check('- long text:\n' - ' \'very "long"\n' - ' \'\'string\'\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\'\n', conf) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check( + '- long text: \'very "long"\n' + " ''string'' with\n" + '\n' + ' paragraph gap, \\n and\n' + " spaces.'\n", + conf, + ) + self.check( + '- long text: \'very "long"\n' + " ''string'' with\n" + '\n' + ' paragraph gap, \\n and\n' + " spaces.'\n", + conf, + problem1=(2, 5), + problem2=(4, 5), + problem3=(5, 5), + ) + self.check( + '- long text: \'very "long"\n' + "''string'' with\n" + '\n' + 'paragraph gap, \\n and\n' + "spaces.'\n", + conf, + problem1=(2, 1), + problem2=(4, 1), + problem3=(5, 1), + ) + self.check( + '- long text:\n' + ' \'very "long"\n' + " ''string'' with\n" + '\n' + ' paragraph gap, \\n and\n' + " spaces.'\n", + conf, + ) def test_paragraph_folded(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('- long text: >\n' - ' very "long"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\n', conf) - self.check('- long text: >\n' - ' very "long"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\n', conf, - problem1=(3, 6), problem2=(5, 7), problem3=(6, 8)) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check( + '- long text: >\n' + ' very "long"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces.\n', + conf, + ) + self.check( + '- long text: >\n' + ' very "long"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces.\n', + conf, + problem1=(3, 6), + problem2=(5, 7), + problem3=(6, 8), + ) def test_paragraph_literal(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('- long text: |\n' - ' very "long"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\n', conf) - self.check('- long text: |\n' - ' very "long"\n' - ' \'string\' with\n' - '\n' - ' paragraph gap, \\n and\n' - ' spaces.\n', conf, - problem1=(3, 6), problem2=(5, 7), problem3=(6, 8)) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check( + '- long text: |\n' + ' very "long"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces.\n', + conf, + ) + self.check( + '- long text: |\n' + ' very "long"\n' + " 'string' with\n" + '\n' + ' paragraph gap, \\n and\n' + ' spaces.\n', + conf, + problem1=(3, 6), + problem2=(5, 7), + problem3=(6, 8), + ) def test_consistent(self): - conf = ('indentation: {spaces: consistent,\n' - ' check-multi-line-strings: true}\n' - 'document-start: disable\n') - self.check('multi\n' - 'line\n', conf) - self.check('multi\n' - ' line\n', conf, problem=(2, 2)) - self.check('- multi\n' - ' line\n', conf) - self.check('- multi\n' - ' line\n', conf, problem=(2, 4)) - self.check('a key: multi\n' - ' line\n', conf, problem=(2, 3)) - self.check('a key: multi\n' - ' line\n', conf, problem=(2, 9)) - self.check('a key:\n' - ' multi\n' - ' line\n', conf, problem=(3, 4)) - self.check('- C code: void main() {\n' - ' printf("foo");\n' - ' }\n', conf, problem=(2, 15)) - self.check('- C code:\n' - ' void main() {\n' - ' printf("foo");\n' - ' }\n', conf, problem=(3, 9)) - self.check('>\n' - ' multi\n' - ' line\n', conf) - self.check('>\n' - ' multi\n' - ' line\n', conf) - self.check('>\n' - ' multi\n' - ' line\n', conf, problem=(3, 7)) + conf = ( + 'indentation: {spaces: consistent,\n' + ' check-multi-line-strings: true}\n' + 'document-start: disable\n' + ) + self.check('multi\n' 'line\n', conf) + self.check('multi\n' ' line\n', conf, problem=(2, 2)) + self.check('- multi\n' ' line\n', conf) + self.check('- multi\n' ' line\n', conf, problem=(2, 4)) + self.check('a key: multi\n' ' line\n', conf, problem=(2, 3)) + self.check('a key: multi\n' ' line\n', conf, problem=(2, 9)) + self.check('a key:\n' ' multi\n' ' line\n', conf, problem=(3, 4)) + self.check( + '- C code: void main() {\n' + ' printf("foo");\n' + ' }\n', + conf, + problem=(2, 15), + ) + self.check( + '- C code:\n' ' void main() {\n' ' printf("foo");\n' ' }\n', + conf, + problem=(3, 9), + ) + self.check('>\n' ' multi\n' ' line\n', conf) + self.check('>\n' ' multi\n' ' line\n', conf) + self.check('>\n' ' multi\n' ' line\n', conf, problem=(3, 7)) diff --git a/tests/rules/test_key_duplicates.py b/tests/rules/test_key_duplicates.py index c1704e68..dfa2f906 100644 --- a/tests/rules/test_key_duplicates.py +++ b/tests/rules/test_key_duplicates.py @@ -21,215 +21,263 @@ class KeyDuplicatesTestCase(RuleTestCase): def test_disabled(self): conf = 'key-duplicates: disable' - self.check('---\n' - 'block mapping:\n' - ' key: a\n' - ' otherkey: b\n' - ' key: c\n', conf) - self.check('---\n' - 'flow mapping:\n' - ' {key: a, otherkey: b, key: c}\n', conf) - self.check('---\n' - 'duplicated twice:\n' - ' - k: a\n' - ' ok: b\n' - ' k: c\n' - ' k: d\n', conf) - self.check('---\n' - 'duplicated twice:\n' - ' - {k: a, ok: b, k: c, k: d}\n', conf) - self.check('---\n' - 'multiple duplicates:\n' - ' a: 1\n' - ' b: 2\n' - ' c: 3\n' - ' d: 4\n' - ' d: 5\n' - ' b: 6\n', conf) - self.check('---\n' - 'multiple duplicates:\n' - ' {a: 1, b: 2, c: 3, d: 4, d: 5, b: 6}\n', conf) - self.check('---\n' - 'at: root\n' - 'multiple: times\n' - 'at: root\n', conf) - self.check('---\n' - 'nested but OK:\n' - ' a: {a: {a: 1}}\n' - ' b:\n' - ' b: 2\n' - ' c: 3\n', conf) - self.check('---\n' - 'nested duplicates:\n' - ' a: {a: 1, a: 1}\n' - ' b:\n' - ' c: 3\n' - ' d: 4\n' - ' d: 4\n' - ' b: 2\n', conf) - self.check('---\n' - 'duplicates with many styles: 1\n' - '"duplicates with many styles": 1\n' - '\'duplicates with many styles\': 1\n' - '? duplicates with many styles\n' - ': 1\n' - '? >-\n' - ' duplicates with\n' - ' many styles\n' - ': 1\n', conf) - self.check('---\n' - 'Merge Keys are OK:\n' - 'anchor_one: &anchor_one\n' - ' one: one\n' - 'anchor_two: &anchor_two\n' - ' two: two\n' - 'anchor_reference:\n' - ' <<: *anchor_one\n' - ' <<: *anchor_two\n', conf) - self.check('---\n' - '{a: 1, b: 2}}\n', conf, problem=(2, 13, 'syntax')) - self.check('---\n' - '[a, b, c]]\n', conf, problem=(2, 10, 'syntax')) + self.check( + '---\n' 'block mapping:\n' ' key: a\n' ' otherkey: b\n' ' key: c\n', conf + ) + self.check('---\n' 'flow mapping:\n' ' {key: a, otherkey: b, key: c}\n', conf) + self.check( + '---\n' + 'duplicated twice:\n' + ' - k: a\n' + ' ok: b\n' + ' k: c\n' + ' k: d\n', + conf, + ) + self.check( + '---\n' 'duplicated twice:\n' ' - {k: a, ok: b, k: c, k: d}\n', conf + ) + self.check( + '---\n' + 'multiple duplicates:\n' + ' a: 1\n' + ' b: 2\n' + ' c: 3\n' + ' d: 4\n' + ' d: 5\n' + ' b: 6\n', + conf, + ) + self.check( + '---\n' 'multiple duplicates:\n' ' {a: 1, b: 2, c: 3, d: 4, d: 5, b: 6}\n', + conf, + ) + self.check('---\n' 'at: root\n' 'multiple: times\n' 'at: root\n', conf) + self.check( + '---\n' + 'nested but OK:\n' + ' a: {a: {a: 1}}\n' + ' b:\n' + ' b: 2\n' + ' c: 3\n', + conf, + ) + self.check( + '---\n' + 'nested duplicates:\n' + ' a: {a: 1, a: 1}\n' + ' b:\n' + ' c: 3\n' + ' d: 4\n' + ' d: 4\n' + ' b: 2\n', + conf, + ) + self.check( + '---\n' + 'duplicates with many styles: 1\n' + '"duplicates with many styles": 1\n' + "'duplicates with many styles': 1\n" + '? duplicates with many styles\n' + ': 1\n' + '? >-\n' + ' duplicates with\n' + ' many styles\n' + ': 1\n', + conf, + ) + self.check( + '---\n' + 'Merge Keys are OK:\n' + 'anchor_one: &anchor_one\n' + ' one: one\n' + 'anchor_two: &anchor_two\n' + ' two: two\n' + 'anchor_reference:\n' + ' <<: *anchor_one\n' + ' <<: *anchor_two\n', + conf, + ) + self.check('---\n' '{a: 1, b: 2}}\n', conf, problem=(2, 13, 'syntax')) + self.check('---\n' '[a, b, c]]\n', conf, problem=(2, 10, 'syntax')) def test_enabled(self): conf = 'key-duplicates: enable' - self.check('---\n' - 'block mapping:\n' - ' key: a\n' - ' otherkey: b\n' - ' key: c\n', conf, - problem=(5, 3)) - self.check('---\n' - 'flow mapping:\n' - ' {key: a, otherkey: b, key: c}\n', conf, - problem=(3, 25)) - self.check('---\n' - 'duplicated twice:\n' - ' - k: a\n' - ' ok: b\n' - ' k: c\n' - ' k: d\n', conf, - problem1=(5, 5), problem2=(6, 5)) - self.check('---\n' - 'duplicated twice:\n' - ' - {k: a, ok: b, k: c, k: d}\n', conf, - problem1=(3, 19), problem2=(3, 25)) - self.check('---\n' - 'multiple duplicates:\n' - ' a: 1\n' - ' b: 2\n' - ' c: 3\n' - ' d: 4\n' - ' d: 5\n' - ' b: 6\n', conf, - problem1=(7, 3), problem2=(8, 3)) - self.check('---\n' - 'multiple duplicates:\n' - ' {a: 1, b: 2, c: 3, d: 4, d: 5, b: 6}\n', conf, - problem1=(3, 28), problem2=(3, 34)) - self.check('---\n' - 'at: root\n' - 'multiple: times\n' - 'at: root\n', conf, - problem=(4, 1)) - self.check('---\n' - 'nested but OK:\n' - ' a: {a: {a: 1}}\n' - ' b:\n' - ' b: 2\n' - ' c: 3\n', conf) - self.check('---\n' - 'nested duplicates:\n' - ' a: {a: 1, a: 1}\n' - ' b:\n' - ' c: 3\n' - ' d: 4\n' - ' d: 4\n' - ' b: 2\n', conf, - problem1=(3, 13), problem2=(7, 5), problem3=(8, 3)) - self.check('---\n' - 'duplicates with many styles: 1\n' - '"duplicates with many styles": 1\n' - '\'duplicates with many styles\': 1\n' - '? duplicates with many styles\n' - ': 1\n' - '? >-\n' - ' duplicates with\n' - ' many styles\n' - ': 1\n', conf, - problem1=(3, 1), problem2=(4, 1), problem3=(5, 3), - problem4=(7, 3)) - self.check('---\n' - 'Merge Keys are OK:\n' - 'anchor_one: &anchor_one\n' - ' one: one\n' - 'anchor_two: &anchor_two\n' - ' two: two\n' - 'anchor_reference:\n' - ' <<: *anchor_one\n' - ' <<: *anchor_two\n', conf) - self.check('---\n' - '{a: 1, b: 2}}\n', conf, problem=(2, 13, 'syntax')) - self.check('---\n' - '[a, b, c]]\n', conf, problem=(2, 10, 'syntax')) + self.check( + '---\n' 'block mapping:\n' ' key: a\n' ' otherkey: b\n' ' key: c\n', + conf, + problem=(5, 3), + ) + self.check( + '---\n' 'flow mapping:\n' ' {key: a, otherkey: b, key: c}\n', + conf, + problem=(3, 25), + ) + self.check( + '---\n' + 'duplicated twice:\n' + ' - k: a\n' + ' ok: b\n' + ' k: c\n' + ' k: d\n', + conf, + problem1=(5, 5), + problem2=(6, 5), + ) + self.check( + '---\n' 'duplicated twice:\n' ' - {k: a, ok: b, k: c, k: d}\n', + conf, + problem1=(3, 19), + problem2=(3, 25), + ) + self.check( + '---\n' + 'multiple duplicates:\n' + ' a: 1\n' + ' b: 2\n' + ' c: 3\n' + ' d: 4\n' + ' d: 5\n' + ' b: 6\n', + conf, + problem1=(7, 3), + problem2=(8, 3), + ) + self.check( + '---\n' 'multiple duplicates:\n' ' {a: 1, b: 2, c: 3, d: 4, d: 5, b: 6}\n', + conf, + problem1=(3, 28), + problem2=(3, 34), + ) + self.check( + '---\n' 'at: root\n' 'multiple: times\n' 'at: root\n', conf, problem=(4, 1) + ) + self.check( + '---\n' + 'nested but OK:\n' + ' a: {a: {a: 1}}\n' + ' b:\n' + ' b: 2\n' + ' c: 3\n', + conf, + ) + self.check( + '---\n' + 'nested duplicates:\n' + ' a: {a: 1, a: 1}\n' + ' b:\n' + ' c: 3\n' + ' d: 4\n' + ' d: 4\n' + ' b: 2\n', + conf, + problem1=(3, 13), + problem2=(7, 5), + problem3=(8, 3), + ) + self.check( + '---\n' + 'duplicates with many styles: 1\n' + '"duplicates with many styles": 1\n' + "'duplicates with many styles': 1\n" + '? duplicates with many styles\n' + ': 1\n' + '? >-\n' + ' duplicates with\n' + ' many styles\n' + ': 1\n', + conf, + problem1=(3, 1), + problem2=(4, 1), + problem3=(5, 3), + problem4=(7, 3), + ) + self.check( + '---\n' + 'Merge Keys are OK:\n' + 'anchor_one: &anchor_one\n' + ' one: one\n' + 'anchor_two: &anchor_two\n' + ' two: two\n' + 'anchor_reference:\n' + ' <<: *anchor_one\n' + ' <<: *anchor_two\n', + conf, + ) + self.check('---\n' '{a: 1, b: 2}}\n', conf, problem=(2, 13, 'syntax')) + self.check('---\n' '[a, b, c]]\n', conf, problem=(2, 10, 'syntax')) def test_key_tokens_in_flow_sequences(self): conf = 'key-duplicates: enable' - self.check('---\n' - '[\n' - ' flow: sequence, with, key: value, mappings\n' - ']\n', conf) + self.check( + '---\n' '[\n' ' flow: sequence, with, key: value, mappings\n' ']\n', conf + ) def test_forbid_duplicated_merge_keys(self): conf = 'key-duplicates: {forbid-duplicated-merge-keys: true}' - self.check('---\n' - 'Multiple Merge Keys are NOT OK:\n' - 'anchor_one: &anchor_one\n' - ' one: one\n' - 'anchor_two: &anchor_two\n' - ' two: two\n' - 'anchor_reference:\n' - ' <<: *anchor_one\n' - ' <<: *anchor_two\n', conf, problem=(9, 3)) - self.check('---\n' - 'Multiple Merge Keys are NOT OK:\n' - 'anchor_one: &anchor_one\n' - ' one: one\n' - 'anchor_two: &anchor_two\n' - ' two: two\n' - 'anchor_three: &anchor_three\n' - ' two: three\n' - 'anchor_reference:\n' - ' <<: *anchor_one\n' - ' <<: *anchor_two\n' - ' <<: *anchor_three\n', conf, - problem1=(11, 3), problem2=(12, 3)) - self.check('---\n' - 'Multiple Merge Keys are NOT OK:\n' - 'anchor_one: &anchor_one\n' - ' one: one\n' - 'anchor_two: &anchor_two\n' - ' two: two\n' - 'anchor_reference:\n' - ' a: 1\n' - ' <<: *anchor_one\n' - ' b: 2\n' - ' <<: *anchor_two\n', conf, problem=(11, 3)) - self.check('---\n' - 'Single Merge Key is OK:\n' - 'anchor_one: &anchor_one\n' - ' one: one\n' - 'anchor_two: &anchor_two\n' - ' two: two\n' - 'anchor_reference:\n' - ' <<: [*anchor_one, *anchor_two]\n', conf) - self.check('---\n' - 'Duplicate keys without Merge Keys:\n' - ' key: a\n' - ' otherkey: b\n' - ' key: c\n', conf, - problem=(5, 3)) - self.check('---\n' - 'No Merge Keys:\n' - ' key: a\n' - ' otherkey: b\n', conf) + self.check( + '---\n' + 'Multiple Merge Keys are NOT OK:\n' + 'anchor_one: &anchor_one\n' + ' one: one\n' + 'anchor_two: &anchor_two\n' + ' two: two\n' + 'anchor_reference:\n' + ' <<: *anchor_one\n' + ' <<: *anchor_two\n', + conf, + problem=(9, 3), + ) + self.check( + '---\n' + 'Multiple Merge Keys are NOT OK:\n' + 'anchor_one: &anchor_one\n' + ' one: one\n' + 'anchor_two: &anchor_two\n' + ' two: two\n' + 'anchor_three: &anchor_three\n' + ' two: three\n' + 'anchor_reference:\n' + ' <<: *anchor_one\n' + ' <<: *anchor_two\n' + ' <<: *anchor_three\n', + conf, + problem1=(11, 3), + problem2=(12, 3), + ) + self.check( + '---\n' + 'Multiple Merge Keys are NOT OK:\n' + 'anchor_one: &anchor_one\n' + ' one: one\n' + 'anchor_two: &anchor_two\n' + ' two: two\n' + 'anchor_reference:\n' + ' a: 1\n' + ' <<: *anchor_one\n' + ' b: 2\n' + ' <<: *anchor_two\n', + conf, + problem=(11, 3), + ) + self.check( + '---\n' + 'Single Merge Key is OK:\n' + 'anchor_one: &anchor_one\n' + ' one: one\n' + 'anchor_two: &anchor_two\n' + ' two: two\n' + 'anchor_reference:\n' + ' <<: [*anchor_one, *anchor_two]\n', + conf, + ) + self.check( + '---\n' + 'Duplicate keys without Merge Keys:\n' + ' key: a\n' + ' otherkey: b\n' + ' key: c\n', + conf, + problem=(5, 3), + ) + self.check('---\n' 'No Merge Keys:\n' ' key: a\n' ' otherkey: b\n', conf) diff --git a/tests/rules/test_key_ordering.py b/tests/rules/test_key_ordering.py index 7d17603e..5384c453 100644 --- a/tests/rules/test_key_ordering.py +++ b/tests/rules/test_key_ordering.py @@ -23,94 +23,75 @@ class KeyOrderingTestCase(RuleTestCase): def test_disabled(self): conf = 'key-ordering: disable' - self.check('---\n' - 'block mapping:\n' - ' secondkey: a\n' - ' firstkey: b\n', conf) - self.check('---\n' - 'flow mapping:\n' - ' {secondkey: a, firstkey: b}\n', conf) - self.check('---\n' - 'second: before_first\n' - 'at: root\n', conf) - self.check('---\n' - 'nested but OK:\n' - ' second: {first: 1}\n' - ' third:\n' - ' second: 2\n', conf) + self.check( + '---\n' 'block mapping:\n' ' secondkey: a\n' ' firstkey: b\n', conf + ) + self.check('---\n' 'flow mapping:\n' ' {secondkey: a, firstkey: b}\n', conf) + self.check('---\n' 'second: before_first\n' 'at: root\n', conf) + self.check( + '---\n' + 'nested but OK:\n' + ' second: {first: 1}\n' + ' third:\n' + ' second: 2\n', + conf, + ) def test_enabled(self): conf = 'key-ordering: enable' - self.check('---\n' - 'block mapping:\n' - ' secondkey: a\n' - ' firstkey: b\n', conf, - problem=(4, 3)) - self.check('---\n' - 'flow mapping:\n' - ' {secondkey: a, firstkey: b}\n', conf, - problem=(3, 18)) - self.check('---\n' - 'second: before_first\n' - 'at: root\n', conf, - problem=(3, 1)) - self.check('---\n' - 'nested but OK:\n' - ' second: {first: 1}\n' - ' third:\n' - ' second: 2\n', conf) + self.check( + '---\n' 'block mapping:\n' ' secondkey: a\n' ' firstkey: b\n', + conf, + problem=(4, 3), + ) + self.check( + '---\n' 'flow mapping:\n' ' {secondkey: a, firstkey: b}\n', + conf, + problem=(3, 18), + ) + self.check('---\n' 'second: before_first\n' 'at: root\n', conf, problem=(3, 1)) + self.check( + '---\n' + 'nested but OK:\n' + ' second: {first: 1}\n' + ' third:\n' + ' second: 2\n', + conf, + ) def test_word_length(self): conf = 'key-ordering: enable' - self.check('---\n' - 'a: 1\n' - 'ab: 1\n' - 'abc: 1\n', conf) - self.check('---\n' - 'a: 1\n' - 'abc: 1\n' - 'ab: 1\n', conf, - problem=(4, 1)) + self.check('---\n' 'a: 1\n' 'ab: 1\n' 'abc: 1\n', conf) + self.check('---\n' 'a: 1\n' 'abc: 1\n' 'ab: 1\n', conf, problem=(4, 1)) def test_key_duplicates(self): - conf = ('key-duplicates: disable\n' - 'key-ordering: enable') - self.check('---\n' - 'key: 1\n' - 'key: 2\n', conf) + conf = 'key-duplicates: disable\n' 'key-ordering: enable' + self.check('---\n' 'key: 1\n' 'key: 2\n', conf) def test_case(self): conf = 'key-ordering: enable' - self.check('---\n' - 'T-shirt: 1\n' - 'T-shirts: 2\n' - 't-shirt: 3\n' - 't-shirts: 4\n', conf) - self.check('---\n' - 'T-shirt: 1\n' - 't-shirt: 2\n' - 'T-shirts: 3\n' - 't-shirts: 4\n', conf, - problem=(4, 1)) + self.check( + '---\n' 'T-shirt: 1\n' 'T-shirts: 2\n' 't-shirt: 3\n' 't-shirts: 4\n', conf + ) + self.check( + '---\n' 'T-shirt: 1\n' 't-shirt: 2\n' 'T-shirts: 3\n' 't-shirts: 4\n', + conf, + problem=(4, 1), + ) def test_accents(self): conf = 'key-ordering: enable' - self.check('---\n' - 'hair: true\n' - 'hais: true\n' - 'haïr: true\n' - 'haïssable: true\n', conf) - self.check('---\n' - 'haïr: true\n' - 'hais: true\n', conf, - problem=(3, 1)) + self.check( + '---\n' 'hair: true\n' 'hais: true\n' 'haïr: true\n' 'haïssable: true\n', + conf, + ) + self.check('---\n' 'haïr: true\n' 'hais: true\n', conf, problem=(3, 1)) def test_key_tokens_in_flow_sequences(self): conf = 'key-ordering: enable' - self.check('---\n' - '[\n' - ' key: value, mappings, in, flow: sequence\n' - ']\n', conf) + self.check( + '---\n' '[\n' ' key: value, mappings, in, flow: sequence\n' ']\n', conf + ) def test_locale_case(self): self.addCleanup(locale.setlocale, locale.LC_ALL, (None, None)) @@ -118,18 +99,15 @@ def test_locale_case(self): locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') except locale.Error: # pragma: no cover self.skipTest('locale en_US.UTF-8 not available') - conf = ('key-ordering: enable') - self.check('---\n' - 't-shirt: 1\n' - 'T-shirt: 2\n' - 't-shirts: 3\n' - 'T-shirts: 4\n', conf) - self.check('---\n' - 't-shirt: 1\n' - 't-shirts: 2\n' - 'T-shirt: 3\n' - 'T-shirts: 4\n', conf, - problem=(4, 1)) + conf = 'key-ordering: enable' + self.check( + '---\n' 't-shirt: 1\n' 'T-shirt: 2\n' 't-shirts: 3\n' 'T-shirts: 4\n', conf + ) + self.check( + '---\n' 't-shirt: 1\n' 't-shirts: 2\n' 'T-shirt: 3\n' 'T-shirts: 4\n', + conf, + problem=(4, 1), + ) def test_locale_accents(self): self.addCleanup(locale.setlocale, locale.LC_ALL, (None, None)) @@ -137,13 +115,9 @@ def test_locale_accents(self): locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') except locale.Error: # pragma: no cover self.skipTest('locale en_US.UTF-8 not available') - conf = ('key-ordering: enable') - self.check('---\n' - 'hair: true\n' - 'haïr: true\n' - 'hais: true\n' - 'haïssable: true\n', conf) - self.check('---\n' - 'hais: true\n' - 'haïr: true\n', conf, - problem=(3, 1)) + conf = 'key-ordering: enable' + self.check( + '---\n' 'hair: true\n' 'haïr: true\n' 'hais: true\n' 'haïssable: true\n', + conf, + ) + self.check('---\n' 'hais: true\n' 'haïr: true\n', conf, problem=(3, 1)) diff --git a/tests/rules/test_line_length.py b/tests/rules/test_line_length.py index ef681782..565b622a 100644 --- a/tests/rules/test_line_length.py +++ b/tests/rules/test_line_length.py @@ -20,10 +20,12 @@ class LineLengthTestCase(RuleTestCase): rule_id = 'line-length' def test_disabled(self): - conf = ('line-length: disable\n' - 'empty-lines: disable\n' - 'new-line-at-end-of-file: disable\n' - 'document-start: disable\n') + conf = ( + 'line-length: disable\n' + 'empty-lines: disable\n' + 'new-line-at-end-of-file: disable\n' + 'document-start: disable\n' + ) self.check('', conf) self.check('\n', conf) self.check('---\n', conf) @@ -31,15 +33,17 @@ def test_disabled(self): self.check('---\n' + 81 * 'a' + '\n', conf) self.check(1000 * 'b', conf) self.check('---\n' + 1000 * 'b' + '\n', conf) - self.check('content: |\n' - ' {% this line is' + 99 * ' really' + ' long %}\n', - conf) + self.check( + 'content: |\n' ' {% this line is' + 99 * ' really' + ' long %}\n', conf + ) def test_default(self): - conf = ('line-length: {max: 80}\n' - 'empty-lines: disable\n' - 'new-line-at-end-of-file: disable\n' - 'document-start: disable\n') + conf = ( + 'line-length: {max: 80}\n' + 'empty-lines: disable\n' + 'new-line-at-end-of-file: disable\n' + 'document-start: disable\n' + ) self.check('', conf) self.check('\n', conf) self.check('---\n', conf) @@ -51,147 +55,211 @@ def test_default(self): self.check('---\n' + 1000 * 'word ' + 'end\n', conf, problem=(2, 81)) def test_max_length_10(self): - conf = ('line-length: {max: 10}\n' - 'new-line-at-end-of-file: disable\n') + conf = 'line-length: {max: 10}\n' 'new-line-at-end-of-file: disable\n' self.check('---\nABCD EFGHI', conf) self.check('---\nABCD EFGHIJ', conf, problem=(2, 11)) self.check('---\nABCD EFGHIJ\n', conf, problem=(2, 11)) def test_spaces(self): - conf = ('line-length: {max: 80}\n' - 'new-line-at-end-of-file: disable\n' - 'trailing-spaces: disable\n') + conf = ( + 'line-length: {max: 80}\n' + 'new-line-at-end-of-file: disable\n' + 'trailing-spaces: disable\n' + ) self.check('---\n' + 81 * ' ', conf, problem=(2, 81)) self.check('---\n' + 81 * ' ' + '\n', conf, problem=(2, 81)) def test_non_breakable_word(self): conf = 'line-length: {max: 20, allow-non-breakable-words: true}' self.check('---\n' + 30 * 'A' + '\n', conf) - self.check('---\n' - 'this:\n' - ' is:\n' - ' - a:\n' - ' http://localhost/very/long/url\n' - '...\n', conf) - self.check('---\n' - 'this:\n' - ' is:\n' - ' - a:\n' - ' # http://localhost/very/long/url\n' - ' comment\n' - '...\n', conf) - self.check('---\n' - 'this:\n' - 'is:\n' - 'another:\n' - ' - https://localhost/very/very/long/url\n' - '...\n', conf) - self.check('---\n' - 'long_line: http://localhost/very/very/long/url\n', conf, - problem=(2, 21)) + self.check( + '---\n' + 'this:\n' + ' is:\n' + ' - a:\n' + ' http://localhost/very/long/url\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'this:\n' + ' is:\n' + ' - a:\n' + ' # http://localhost/very/long/url\n' + ' comment\n' + '...\n', + conf, + ) + self.check( + '---\n' + 'this:\n' + 'is:\n' + 'another:\n' + ' - https://localhost/very/very/long/url\n' + '...\n', + conf, + ) + self.check( + '---\n' 'long_line: http://localhost/very/very/long/url\n', + conf, + problem=(2, 21), + ) conf = 'line-length: {max: 20, allow-non-breakable-words: false}' self.check('---\n' + 30 * 'A' + '\n', conf, problem=(2, 21)) - self.check('---\n' - 'this:\n' - ' is:\n' - ' - a:\n' - ' http://localhost/very/long/url\n' - '...\n', conf, problem=(5, 21)) - self.check('---\n' - 'this:\n' - ' is:\n' - ' - a:\n' - ' # http://localhost/very/long/url\n' - ' comment\n' - '...\n', conf, problem=(5, 21)) - self.check('---\n' - 'this:\n' - 'is:\n' - 'another:\n' - ' - https://localhost/very/very/long/url\n' - '...\n', conf, problem=(5, 21)) - self.check('---\n' - 'long_line: http://localhost/very/very/long/url\n' - '...\n', conf, problem=(2, 21)) + self.check( + '---\n' + 'this:\n' + ' is:\n' + ' - a:\n' + ' http://localhost/very/long/url\n' + '...\n', + conf, + problem=(5, 21), + ) + self.check( + '---\n' + 'this:\n' + ' is:\n' + ' - a:\n' + ' # http://localhost/very/long/url\n' + ' comment\n' + '...\n', + conf, + problem=(5, 21), + ) + self.check( + '---\n' + 'this:\n' + 'is:\n' + 'another:\n' + ' - https://localhost/very/very/long/url\n' + '...\n', + conf, + problem=(5, 21), + ) + self.check( + '---\n' 'long_line: http://localhost/very/very/long/url\n' '...\n', + conf, + problem=(2, 21), + ) conf = 'line-length: {max: 20, allow-non-breakable-words: true}' - self.check('---\n' - '# http://www.verylongurlurlurlurlurlurlurlurl.com\n' - 'key:\n' - ' subkey: value\n', conf) - self.check('---\n' - '## http://www.verylongurlurlurlurlurlurlurlurl.com\n' - 'key:\n' - ' subkey: value\n', conf) - self.check('---\n' - '# # http://www.verylongurlurlurlurlurlurlurlurl.com\n' - 'key:\n' - ' subkey: value\n', conf, - problem=(2, 21)) - self.check('---\n' - '#A http://www.verylongurlurlurlurlurlurlurlurl.com\n' - 'key:\n' - ' subkey: value\n', conf, - problem1=(2, 2, 'comments'), - problem2=(2, 21, 'line-length')) - - conf = ('line-length: {max: 20, allow-non-breakable-words: true}\n' - 'trailing-spaces: disable') - self.check('---\n' - 'loooooooooong+word+and+some+space+at+the+end \n', - conf, problem=(2, 21)) + self.check( + '---\n' + '# http://www.verylongurlurlurlurlurlurlurlurl.com\n' + 'key:\n' + ' subkey: value\n', + conf, + ) + self.check( + '---\n' + '## http://www.verylongurlurlurlurlurlurlurlurl.com\n' + 'key:\n' + ' subkey: value\n', + conf, + ) + self.check( + '---\n' + '# # http://www.verylongurlurlurlurlurlurlurlurl.com\n' + 'key:\n' + ' subkey: value\n', + conf, + problem=(2, 21), + ) + self.check( + '---\n' + '#A http://www.verylongurlurlurlurlurlurlurlurl.com\n' + 'key:\n' + ' subkey: value\n', + conf, + problem1=(2, 2, 'comments'), + problem2=(2, 21, 'line-length'), + ) + + conf = ( + 'line-length: {max: 20, allow-non-breakable-words: true}\n' + 'trailing-spaces: disable' + ) + self.check( + '---\n' 'loooooooooong+word+and+some+space+at+the+end \n', + conf, + problem=(2, 21), + ) def test_non_breakable_inline_mappings(self): - conf = 'line-length: {max: 20, ' \ - 'allow-non-breakable-inline-mappings: true}' - self.check('---\n' - 'long_line: http://localhost/very/very/long/url\n' - 'long line: http://localhost/very/very/long/url\n', conf) - self.check('---\n' - '- long line: http://localhost/very/very/long/url\n', conf) - - self.check('---\n' - 'long_line: http://localhost/short/url + word\n' - 'long line: http://localhost/short/url + word\n', - conf, problem1=(2, 21), problem2=(3, 21)) - - conf = ('line-length: {max: 20,' - ' allow-non-breakable-inline-mappings: true}\n' - 'trailing-spaces: disable') - self.check('---\n' - 'long_line: and+some+space+at+the+end \n', - conf, problem=(2, 21)) - self.check('---\n' - 'long line: and+some+space+at+the+end \n', - conf, problem=(2, 21)) - self.check('---\n' - '- long line: and+some+space+at+the+end \n', - conf, problem=(2, 21)) + conf = 'line-length: {max: 20, ' 'allow-non-breakable-inline-mappings: true}' + self.check( + '---\n' + 'long_line: http://localhost/very/very/long/url\n' + 'long line: http://localhost/very/very/long/url\n', + conf, + ) + self.check('---\n' '- long line: http://localhost/very/very/long/url\n', conf) + + self.check( + '---\n' + 'long_line: http://localhost/short/url + word\n' + 'long line: http://localhost/short/url + word\n', + conf, + problem1=(2, 21), + problem2=(3, 21), + ) + + conf = ( + 'line-length: {max: 20,' + ' allow-non-breakable-inline-mappings: true}\n' + 'trailing-spaces: disable' + ) + self.check( + '---\n' 'long_line: and+some+space+at+the+end \n', + conf, + problem=(2, 21), + ) + self.check( + '---\n' 'long line: and+some+space+at+the+end \n', + conf, + problem=(2, 21), + ) + self.check( + '---\n' '- long line: and+some+space+at+the+end \n', + conf, + problem=(2, 21), + ) # See https://github.com/adrienverge/yamllint/issues/21 conf = 'line-length: {allow-non-breakable-inline-mappings: true}' - self.check('---\n' - 'content: |\n' - ' {% this line is' + 99 * ' really' + ' long %}\n', - conf, problem=(3, 81)) + self.check( + '---\n' 'content: |\n' ' {% this line is' + 99 * ' really' + ' long %}\n', + conf, + problem=(3, 81), + ) def test_unicode(self): conf = 'line-length: {max: 53}' - self.check('---\n' - '# This is a test to check if “line-length” works nice\n' - 'with: “unicode characters” that span across bytes! ↺\n', - conf) + self.check( + '---\n' + '# This is a test to check if “line-length” works nice\n' + 'with: “unicode characters” that span across bytes! ↺\n', + conf, + ) conf = 'line-length: {max: 51}' - self.check('---\n' - '# This is a test to check if “line-length” works nice\n' - 'with: “unicode characters” that span across bytes! ↺\n', - conf, problem1=(2, 52), problem2=(3, 52)) + self.check( + '---\n' + '# This is a test to check if “line-length” works nice\n' + 'with: “unicode characters” that span across bytes! ↺\n', + conf, + problem1=(2, 52), + problem2=(3, 52), + ) def test_with_dos_newlines(self): - conf = ('line-length: {max: 10}\n' - 'new-lines: {type: dos}\n' - 'new-line-at-end-of-file: disable\n') + conf = ( + 'line-length: {max: 10}\n' + 'new-lines: {type: dos}\n' + 'new-line-at-end-of-file: disable\n' + ) self.check('---\r\nABCD EFGHI', conf) self.check('---\r\nABCD EFGHI\r\n', conf) self.check('---\r\nABCD EFGHIJ', conf, problem=(2, 11)) diff --git a/tests/rules/test_new_line_at_end_of_file.py b/tests/rules/test_new_line_at_end_of_file.py index 10a0bf0e..f659bbdb 100644 --- a/tests/rules/test_new_line_at_end_of_file.py +++ b/tests/rules/test_new_line_at_end_of_file.py @@ -20,22 +20,24 @@ class NewLineAtEndOfFileTestCase(RuleTestCase): rule_id = 'new-line-at-end-of-file' def test_disabled(self): - conf = ('new-line-at-end-of-file: disable\n' - 'empty-lines: disable\n' - 'document-start: disable\n') + conf = ( + 'new-line-at-end-of-file: disable\n' + 'empty-lines: disable\n' + 'document-start: disable\n' + ) self.check('', conf) self.check('\n', conf) self.check('word', conf) self.check('Sentence.\n', conf) def test_enabled(self): - conf = ('new-line-at-end-of-file: enable\n' - 'empty-lines: disable\n' - 'document-start: disable\n') + conf = ( + 'new-line-at-end-of-file: enable\n' + 'empty-lines: disable\n' + 'document-start: disable\n' + ) self.check('', conf) self.check('\n', conf) self.check('word', conf, problem=(1, 5)) self.check('Sentence.\n', conf) - self.check('---\n' - 'yaml: document\n' - '...', conf, problem=(3, 4)) + self.check('---\n' 'yaml: document\n' '...', conf, problem=(3, 4)) diff --git a/tests/rules/test_new_lines.py b/tests/rules/test_new_lines.py index 80334ead..7e677fee 100644 --- a/tests/rules/test_new_lines.py +++ b/tests/rules/test_new_lines.py @@ -22,8 +22,7 @@ class NewLinesTestCase(RuleTestCase): rule_id = 'new-lines' def test_disabled(self): - conf = ('new-line-at-end-of-file: disable\n' - 'new-lines: disable\n') + conf = 'new-line-at-end-of-file: disable\n' 'new-lines: disable\n' self.check('', conf) self.check('\n', conf) self.check('\r', conf) @@ -32,8 +31,7 @@ def test_disabled(self): self.check('---\r\ntext\r\n', conf) def test_unix_type(self): - conf = ('new-line-at-end-of-file: disable\n' - 'new-lines: {type: unix}\n') + conf = 'new-line-at-end-of-file: disable\n' 'new-lines: {type: unix}\n' self.check('', conf) self.check('\r', conf) self.check('\n', conf) @@ -45,15 +43,16 @@ def test_unix_type_required_st_sp(self): # If we find a CRLF when looking for Unix newlines, yamllint # should always raise, regardless of logic with # require-starting-space. - conf = ('new-line-at-end-of-file: disable\n' - 'new-lines: {type: unix}\n' - 'comments:\n' - ' require-starting-space: true\n') + conf = ( + 'new-line-at-end-of-file: disable\n' + 'new-lines: {type: unix}\n' + 'comments:\n' + ' require-starting-space: true\n' + ) self.check('---\r\n#\r\n', conf, problem=(1, 4)) def test_dos_type(self): - conf = ('new-line-at-end-of-file: disable\n' - 'new-lines: {type: dos}\n') + conf = 'new-line-at-end-of-file: disable\n' 'new-lines: {type: dos}\n' self.check('', conf) self.check('\r', conf) self.check('\n', conf, problem=(1, 1)) @@ -62,8 +61,7 @@ def test_dos_type(self): self.check('---\r\ntext\r\n', conf) def test_platform_type(self): - conf = ('new-line-at-end-of-file: disable\n' - 'new-lines: {type: platform}\n') + conf = 'new-line-at-end-of-file: disable\n' 'new-lines: {type: platform}\n' self.check('', conf) diff --git a/tests/rules/test_octal_values.py b/tests/rules/test_octal_values.py index be5b039e..1c4106a7 100644 --- a/tests/rules/test_octal_values.py +++ b/tests/rules/test_octal_values.py @@ -20,61 +20,59 @@ class OctalValuesTestCase(RuleTestCase): rule_id = 'octal-values' def test_disabled(self): - conf = ('octal-values: disable\n' - 'new-line-at-end-of-file: disable\n' - 'document-start: disable\n') + conf = ( + 'octal-values: disable\n' + 'new-line-at-end-of-file: disable\n' + 'document-start: disable\n' + ) self.check('user-city: 010', conf) self.check('user-city: 0o10', conf) def test_implicit_octal_values(self): - conf = ('octal-values:\n' - ' forbid-implicit-octal: true\n' - ' forbid-explicit-octal: false\n' - 'new-line-at-end-of-file: disable\n' - 'document-start: disable\n') + conf = ( + 'octal-values:\n' + ' forbid-implicit-octal: true\n' + ' forbid-explicit-octal: false\n' + 'new-line-at-end-of-file: disable\n' + 'document-start: disable\n' + ) self.check('after-tag: !custom_tag 010', conf) self.check('user-city: 010', conf, problem=(1, 15)) self.check('user-city: abc', conf) self.check('user-city: 010,0571', conf) self.check("user-city: '010'", conf) self.check('user-city: "010"', conf) - self.check('user-city:\n' - ' - 010', conf, problem=(2, 8)) + self.check('user-city:\n' ' - 010', conf, problem=(2, 8)) self.check('user-city: [010]', conf, problem=(1, 16)) self.check('user-city: {beijing: 010}', conf, problem=(1, 25)) self.check('explicit-octal: 0o10', conf) self.check('not-number: 0abc', conf) self.check('zero: 0', conf) self.check('hex-value: 0x10', conf) - self.check('number-values:\n' - ' - 0.10\n' - ' - .01\n' - ' - 0e3\n', conf) + self.check('number-values:\n' ' - 0.10\n' ' - .01\n' ' - 0e3\n', conf) self.check('with-decimal-digits: 012345678', conf) self.check('with-decimal-digits: 012345679', conf) def test_explicit_octal_values(self): - conf = ('octal-values:\n' - ' forbid-implicit-octal: false\n' - ' forbid-explicit-octal: true\n' - 'new-line-at-end-of-file: disable\n' - 'document-start: disable\n') + conf = ( + 'octal-values:\n' + ' forbid-implicit-octal: false\n' + ' forbid-explicit-octal: true\n' + 'new-line-at-end-of-file: disable\n' + 'document-start: disable\n' + ) self.check('user-city: 0o10', conf, problem=(1, 16)) self.check('user-city: abc', conf) self.check('user-city: 0o10,0571', conf) self.check("user-city: '0o10'", conf) - self.check('user-city:\n' - ' - 0o10', conf, problem=(2, 9)) + self.check('user-city:\n' ' - 0o10', conf, problem=(2, 9)) self.check('user-city: [0o10]', conf, problem=(1, 17)) self.check('user-city: {beijing: 0o10}', conf, problem=(1, 26)) self.check('implicit-octal: 010', conf) self.check('not-number: 0oabc', conf) self.check('zero: 0', conf) self.check('hex-value: 0x10', conf) - self.check('number-values:\n' - ' - 0.10\n' - ' - .01\n' - ' - 0e3\n', conf) + self.check('number-values:\n' ' - 0.10\n' ' - .01\n' ' - 0e3\n', conf) self.check('user-city: "010"', conf) self.check('with-decimal-digits: 0o012345678', conf) self.check('with-decimal-digits: 0o012345679', conf) diff --git a/tests/rules/test_quoted_strings.py b/tests/rules/test_quoted_strings.py index 1bcb6f8f..5608b747 100644 --- a/tests/rules/test_quoted_strings.py +++ b/tests/rules/test_quoted_strings.py @@ -24,1293 +24,1635 @@ class QuotedValuesTestCase(RuleTestCase): def test_disabled(self): conf = 'quoted-strings: disable' - self.check('---\n' - 'foo: bar\n', conf) - self.check('---\n' - 'foo: "bar"\n', conf) - self.check('---\n' - 'foo: \'bar\'\n', conf) - self.check('---\n' - 'bar: 123\n', conf) - self.check('---\n' - 'bar: "123"\n', conf) + self.check('---\n' 'foo: bar\n', conf) + self.check('---\n' 'foo: "bar"\n', conf) + self.check('---\n' "foo: 'bar'\n", conf) + self.check('---\n' 'bar: 123\n', conf) + self.check('---\n' 'bar: "123"\n', conf) def test_quote_type_any(self): conf = 'quoted-strings: {quote-type: any}\n' - self.check('---\n' - 'boolean1: true\n' - 'number1: 123\n' - 'string1: foo\n' # fails - 'string2: "foo"\n' - 'string3: "true"\n' - 'string4: "123"\n' - 'string5: \'bar\'\n' - 'string6: !!str genericstring\n' - 'string7: !!str 456\n' - 'string8: !!str "quotedgenericstring"\n' - 'binary: !!binary binstring\n' - 'integer: !!int intstring\n' - 'boolean2: !!bool boolstring\n' - 'boolean3: !!bool "quotedboolstring"\n' - 'block-seq:\n' - ' - foo\n' # fails - ' - "foo"\n' - 'flow-seq: [foo, "foo"]\n' # fails - 'flow-map: {a: foo, b: "foo"}\n' # fails - 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' - 'flow-map2: {a: foo, b: "foo,bar"}\n' - 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' - 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', - conf, problem1=(4, 10), problem2=(17, 5), problem3=(19, 12), - problem4=(20, 15), problem5=(21, 13), problem6=(22, 16), - problem7=(23, 19), problem8=(23, 28), problem9=(24, 20)) - self.check('---\n' - 'multiline string 1: |\n' - ' line 1\n' - ' line 2\n' - 'multiline string 2: >\n' - ' word 1\n' - ' word 2\n' - 'multiline string 3:\n' - ' word 1\n' # fails - ' word 2\n' - 'multiline string 4:\n' - ' "word 1\\\n' - ' word 2"\n', - conf, problem1=(9, 3)) + self.check( + '---\n' + 'boolean1: true\n' + 'number1: 123\n' + 'string1: foo\n' # fails + 'string2: "foo"\n' + 'string3: "true"\n' + 'string4: "123"\n' + "string5: 'bar'\n" + 'string6: !!str genericstring\n' + 'string7: !!str 456\n' + 'string8: !!str "quotedgenericstring"\n' + 'binary: !!binary binstring\n' + 'integer: !!int intstring\n' + 'boolean2: !!bool boolstring\n' + 'boolean3: !!bool "quotedboolstring"\n' + 'block-seq:\n' + ' - foo\n' # fails + ' - "foo"\n' + 'flow-seq: [foo, "foo"]\n' # fails + 'flow-map: {a: foo, b: "foo"}\n' # fails + 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' + 'flow-map2: {a: foo, b: "foo,bar"}\n' + 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' + 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', + conf, + problem1=(4, 10), + problem2=(17, 5), + problem3=(19, 12), + problem4=(20, 15), + problem5=(21, 13), + problem6=(22, 16), + problem7=(23, 19), + problem8=(23, 28), + problem9=(24, 20), + ) + self.check( + '---\n' + 'multiline string 1: |\n' + ' line 1\n' + ' line 2\n' + 'multiline string 2: >\n' + ' word 1\n' + ' word 2\n' + 'multiline string 3:\n' + ' word 1\n' # fails + ' word 2\n' + 'multiline string 4:\n' + ' "word 1\\\n' + ' word 2"\n', + conf, + problem1=(9, 3), + ) def test_quote_type_single(self): conf = 'quoted-strings: {quote-type: single}\n' - self.check('---\n' - 'boolean1: true\n' - 'number1: 123\n' - 'string1: foo\n' # fails - 'string2: "foo"\n' # fails - 'string3: "true"\n' # fails - 'string4: "123"\n' # fails - 'string5: \'bar\'\n' - 'string6: !!str genericstring\n' - 'string7: !!str 456\n' - 'string8: !!str "quotedgenericstring"\n' - 'binary: !!binary binstring\n' - 'integer: !!int intstring\n' - 'boolean2: !!bool boolstring\n' - 'boolean3: !!bool "quotedboolstring"\n' - 'block-seq:\n' - ' - foo\n' # fails - ' - "foo"\n' # fails - 'flow-seq: [foo, "foo"]\n' # fails - 'flow-map: {a: foo, b: "foo"}\n' # fails - 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' - 'flow-map2: {a: foo, b: "foo,bar"}\n' - 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' - 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', - conf, problem1=(4, 10), problem2=(5, 10), problem3=(6, 10), - problem4=(7, 10), problem5=(17, 5), problem6=(18, 5), - problem7=(19, 12), problem8=(19, 17), problem9=(20, 15), - problem10=(20, 23), problem11=(21, 13), problem12=(21, 18), - problem13=(21, 29), problem14=(21, 41), problem15=(22, 16), - problem16=(22, 24), problem17=(23, 19), problem18=(23, 28), - problem19=(23, 33), problem20=(24, 20), problem21=(24, 30), - problem22=(24, 45)) - self.check('---\n' - 'multiline string 1: |\n' - ' line 1\n' - ' line 2\n' - 'multiline string 2: >\n' - ' word 1\n' - ' word 2\n' - 'multiline string 3:\n' - ' word 1\n' # fails - ' word 2\n' - 'multiline string 4:\n' - ' "word 1\\\n' - ' word 2"\n', - conf, problem1=(9, 3), problem2=(12, 3)) + self.check( + '---\n' + 'boolean1: true\n' + 'number1: 123\n' + 'string1: foo\n' # fails + 'string2: "foo"\n' # fails + 'string3: "true"\n' # fails + 'string4: "123"\n' # fails + "string5: 'bar'\n" + 'string6: !!str genericstring\n' + 'string7: !!str 456\n' + 'string8: !!str "quotedgenericstring"\n' + 'binary: !!binary binstring\n' + 'integer: !!int intstring\n' + 'boolean2: !!bool boolstring\n' + 'boolean3: !!bool "quotedboolstring"\n' + 'block-seq:\n' + ' - foo\n' # fails + ' - "foo"\n' # fails + 'flow-seq: [foo, "foo"]\n' # fails + 'flow-map: {a: foo, b: "foo"}\n' # fails + 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' + 'flow-map2: {a: foo, b: "foo,bar"}\n' + 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' + 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', + conf, + problem1=(4, 10), + problem2=(5, 10), + problem3=(6, 10), + problem4=(7, 10), + problem5=(17, 5), + problem6=(18, 5), + problem7=(19, 12), + problem8=(19, 17), + problem9=(20, 15), + problem10=(20, 23), + problem11=(21, 13), + problem12=(21, 18), + problem13=(21, 29), + problem14=(21, 41), + problem15=(22, 16), + problem16=(22, 24), + problem17=(23, 19), + problem18=(23, 28), + problem19=(23, 33), + problem20=(24, 20), + problem21=(24, 30), + problem22=(24, 45), + ) + self.check( + '---\n' + 'multiline string 1: |\n' + ' line 1\n' + ' line 2\n' + 'multiline string 2: >\n' + ' word 1\n' + ' word 2\n' + 'multiline string 3:\n' + ' word 1\n' # fails + ' word 2\n' + 'multiline string 4:\n' + ' "word 1\\\n' + ' word 2"\n', + conf, + problem1=(9, 3), + problem2=(12, 3), + ) def test_quote_type_double(self): conf = 'quoted-strings: {quote-type: double}\n' - self.check('---\n' - 'boolean1: true\n' - 'number1: 123\n' - 'string1: foo\n' # fails - 'string2: "foo"\n' - 'string3: "true"\n' - 'string4: "123"\n' - 'string5: \'bar\'\n' # fails - 'string6: !!str genericstring\n' - 'string7: !!str 456\n' - 'string8: !!str "quotedgenericstring"\n' - 'binary: !!binary binstring\n' - 'integer: !!int intstring\n' - 'boolean2: !!bool boolstring\n' - 'boolean3: !!bool "quotedboolstring"\n' - 'block-seq:\n' - ' - foo\n' # fails - ' - "foo"\n' - 'flow-seq: [foo, "foo"]\n' # fails - 'flow-map: {a: foo, b: "foo"}\n' # fails - 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' - 'flow-map2: {a: foo, b: "foo,bar"}\n' - 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' - 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', - conf, problem1=(4, 10), problem2=(8, 10), problem3=(17, 5), - problem4=(19, 12), problem5=(20, 15), problem6=(21, 13), - problem7=(22, 16), problem8=(23, 19), problem9=(23, 28), - problem10=(24, 20)) - self.check('---\n' - 'multiline string 1: |\n' - ' line 1\n' - ' line 2\n' - 'multiline string 2: >\n' - ' word 1\n' - ' word 2\n' - 'multiline string 3:\n' - ' word 1\n' # fails - ' word 2\n' - 'multiline string 4:\n' - ' "word 1\\\n' - ' word 2"\n', - conf, problem1=(9, 3)) + self.check( + '---\n' + 'boolean1: true\n' + 'number1: 123\n' + 'string1: foo\n' # fails + 'string2: "foo"\n' + 'string3: "true"\n' + 'string4: "123"\n' + "string5: 'bar'\n" # fails + 'string6: !!str genericstring\n' + 'string7: !!str 456\n' + 'string8: !!str "quotedgenericstring"\n' + 'binary: !!binary binstring\n' + 'integer: !!int intstring\n' + 'boolean2: !!bool boolstring\n' + 'boolean3: !!bool "quotedboolstring"\n' + 'block-seq:\n' + ' - foo\n' # fails + ' - "foo"\n' + 'flow-seq: [foo, "foo"]\n' # fails + 'flow-map: {a: foo, b: "foo"}\n' # fails + 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' + 'flow-map2: {a: foo, b: "foo,bar"}\n' + 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' + 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', + conf, + problem1=(4, 10), + problem2=(8, 10), + problem3=(17, 5), + problem4=(19, 12), + problem5=(20, 15), + problem6=(21, 13), + problem7=(22, 16), + problem8=(23, 19), + problem9=(23, 28), + problem10=(24, 20), + ) + self.check( + '---\n' + 'multiline string 1: |\n' + ' line 1\n' + ' line 2\n' + 'multiline string 2: >\n' + ' word 1\n' + ' word 2\n' + 'multiline string 3:\n' + ' word 1\n' # fails + ' word 2\n' + 'multiline string 4:\n' + ' "word 1\\\n' + ' word 2"\n', + conf, + problem1=(9, 3), + ) def test_any_quotes_not_required(self): conf = 'quoted-strings: {quote-type: any, required: false}\n' - self.check('---\n' - 'boolean1: true\n' - 'number1: 123\n' - 'string1: foo\n' - 'string2: "foo"\n' - 'string3: "true"\n' - 'string4: "123"\n' - 'string5: \'bar\'\n' - 'string6: !!str genericstring\n' - 'string7: !!str 456\n' - 'string8: !!str "quotedgenericstring"\n' - 'binary: !!binary binstring\n' - 'integer: !!int intstring\n' - 'boolean2: !!bool boolstring\n' - 'boolean3: !!bool "quotedboolstring"\n' - 'block-seq:\n' - ' - foo\n' # fails - ' - "foo"\n' - 'flow-seq: [foo, "foo"]\n' # fails - 'flow-map: {a: foo, b: "foo"}\n' # fails - 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' - 'flow-map2: {a: foo, b: "foo,bar"}\n' - 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' - 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', - conf) - self.check('---\n' - 'multiline string 1: |\n' - ' line 1\n' - ' line 2\n' - 'multiline string 2: >\n' - ' word 1\n' - ' word 2\n' - 'multiline string 3:\n' - ' word 1\n' - ' word 2\n' - 'multiline string 4:\n' - ' "word 1\\\n' - ' word 2"\n', - conf) + self.check( + '---\n' + 'boolean1: true\n' + 'number1: 123\n' + 'string1: foo\n' + 'string2: "foo"\n' + 'string3: "true"\n' + 'string4: "123"\n' + "string5: 'bar'\n" + 'string6: !!str genericstring\n' + 'string7: !!str 456\n' + 'string8: !!str "quotedgenericstring"\n' + 'binary: !!binary binstring\n' + 'integer: !!int intstring\n' + 'boolean2: !!bool boolstring\n' + 'boolean3: !!bool "quotedboolstring"\n' + 'block-seq:\n' + ' - foo\n' # fails + ' - "foo"\n' + 'flow-seq: [foo, "foo"]\n' # fails + 'flow-map: {a: foo, b: "foo"}\n' # fails + 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' + 'flow-map2: {a: foo, b: "foo,bar"}\n' + 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' + 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', + conf, + ) + self.check( + '---\n' + 'multiline string 1: |\n' + ' line 1\n' + ' line 2\n' + 'multiline string 2: >\n' + ' word 1\n' + ' word 2\n' + 'multiline string 3:\n' + ' word 1\n' + ' word 2\n' + 'multiline string 4:\n' + ' "word 1\\\n' + ' word 2"\n', + conf, + ) def test_single_quotes_not_required(self): conf = 'quoted-strings: {quote-type: single, required: false}\n' - self.check('---\n' - 'boolean1: true\n' - 'number1: 123\n' - 'string1: foo\n' - 'string2: "foo"\n' # fails - 'string3: "true"\n' # fails - 'string4: "123"\n' # fails - 'string5: \'bar\'\n' - 'string6: !!str genericstring\n' - 'string7: !!str 456\n' - 'string8: !!str "quotedgenericstring"\n' - 'binary: !!binary binstring\n' - 'integer: !!int intstring\n' - 'boolean2: !!bool boolstring\n' - 'boolean3: !!bool "quotedboolstring"\n' - 'block-seq:\n' - ' - foo\n' # fails - ' - "foo"\n' - 'flow-seq: [foo, "foo"]\n' # fails - 'flow-map: {a: foo, b: "foo"}\n' # fails - 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' - 'flow-map2: {a: foo, b: "foo,bar"}\n' - 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' - 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', - conf, problem1=(5, 10), problem2=(6, 10), problem3=(7, 10), - problem4=(18, 5), problem5=(19, 17), problem6=(20, 23), - problem7=(21, 18), problem8=(21, 29), problem9=(21, 41), - problem10=(22, 24), problem11=(23, 33), problem12=(24, 30), - problem13=(24, 45)) - self.check('---\n' - 'multiline string 1: |\n' - ' line 1\n' - ' line 2\n' - 'multiline string 2: >\n' - ' word 1\n' - ' word 2\n' - 'multiline string 3:\n' - ' word 1\n' - ' word 2\n' - 'multiline string 4:\n' - ' "word 1\\\n' # fails - ' word 2"\n', - conf, problem1=(12, 3)) + self.check( + '---\n' + 'boolean1: true\n' + 'number1: 123\n' + 'string1: foo\n' + 'string2: "foo"\n' # fails + 'string3: "true"\n' # fails + 'string4: "123"\n' # fails + "string5: 'bar'\n" + 'string6: !!str genericstring\n' + 'string7: !!str 456\n' + 'string8: !!str "quotedgenericstring"\n' + 'binary: !!binary binstring\n' + 'integer: !!int intstring\n' + 'boolean2: !!bool boolstring\n' + 'boolean3: !!bool "quotedboolstring"\n' + 'block-seq:\n' + ' - foo\n' # fails + ' - "foo"\n' + 'flow-seq: [foo, "foo"]\n' # fails + 'flow-map: {a: foo, b: "foo"}\n' # fails + 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' + 'flow-map2: {a: foo, b: "foo,bar"}\n' + 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' + 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', + conf, + problem1=(5, 10), + problem2=(6, 10), + problem3=(7, 10), + problem4=(18, 5), + problem5=(19, 17), + problem6=(20, 23), + problem7=(21, 18), + problem8=(21, 29), + problem9=(21, 41), + problem10=(22, 24), + problem11=(23, 33), + problem12=(24, 30), + problem13=(24, 45), + ) + self.check( + '---\n' + 'multiline string 1: |\n' + ' line 1\n' + ' line 2\n' + 'multiline string 2: >\n' + ' word 1\n' + ' word 2\n' + 'multiline string 3:\n' + ' word 1\n' + ' word 2\n' + 'multiline string 4:\n' + ' "word 1\\\n' # fails + ' word 2"\n', + conf, + problem1=(12, 3), + ) def test_only_when_needed(self): conf = 'quoted-strings: {required: only-when-needed}\n' - self.check('---\n' - 'boolean1: true\n' - 'number1: 123\n' - 'string1: foo\n' - 'string2: "foo"\n' # fails - 'string3: "true"\n' - 'string4: "123"\n' - 'string5: \'bar\'\n' # fails - 'string6: !!str genericstring\n' - 'string7: !!str 456\n' - 'string8: !!str "quotedgenericstring"\n' - 'binary: !!binary binstring\n' - 'integer: !!int intstring\n' - 'boolean2: !!bool boolstring\n' - 'boolean3: !!bool "quotedboolstring"\n' - 'block-seq:\n' - ' - foo\n' - ' - "foo"\n' # fails - 'flow-seq: [foo, "foo"]\n' # fails - 'flow-map: {a: foo, b: "foo"}\n' # fails - 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' - 'flow-map2: {a: foo, b: "foo,bar"}\n' - 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' - 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', - conf, problem1=(5, 10), problem2=(8, 10), problem3=(18, 5), - problem4=(19, 17), problem5=(20, 23)) - self.check('---\n' - 'multiline string 1: |\n' - ' line 1\n' - ' line 2\n' - 'multiline string 2: >\n' - ' word 1\n' - ' word 2\n' - 'multiline string 3:\n' - ' word 1\n' - ' word 2\n' - 'multiline string 4:\n' - ' "word 1\\\n' # fails - ' word 2"\n', - conf, problem1=(12, 3)) + self.check( + '---\n' + 'boolean1: true\n' + 'number1: 123\n' + 'string1: foo\n' + 'string2: "foo"\n' # fails + 'string3: "true"\n' + 'string4: "123"\n' + "string5: 'bar'\n" # fails + 'string6: !!str genericstring\n' + 'string7: !!str 456\n' + 'string8: !!str "quotedgenericstring"\n' + 'binary: !!binary binstring\n' + 'integer: !!int intstring\n' + 'boolean2: !!bool boolstring\n' + 'boolean3: !!bool "quotedboolstring"\n' + 'block-seq:\n' + ' - foo\n' + ' - "foo"\n' # fails + 'flow-seq: [foo, "foo"]\n' # fails + 'flow-map: {a: foo, b: "foo"}\n' # fails + 'flow-seq2: [foo, "foo,bar", "foo[bar]", "foo{bar}"]\n' + 'flow-map2: {a: foo, b: "foo,bar"}\n' + 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' + 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', + conf, + problem1=(5, 10), + problem2=(8, 10), + problem3=(18, 5), + problem4=(19, 17), + problem5=(20, 23), + ) + self.check( + '---\n' + 'multiline string 1: |\n' + ' line 1\n' + ' line 2\n' + 'multiline string 2: >\n' + ' word 1\n' + ' word 2\n' + 'multiline string 3:\n' + ' word 1\n' + ' word 2\n' + 'multiline string 4:\n' + ' "word 1\\\n' # fails + ' word 2"\n', + conf, + problem1=(12, 3), + ) def test_only_when_needed_single_quotes(self): - conf = ('quoted-strings: {quote-type: single,\n' - ' required: only-when-needed}\n') - - self.check('---\n' - 'boolean1: true\n' - 'number1: 123\n' - 'string1: foo\n' - 'string2: "foo"\n' # fails - 'string3: "true"\n' # fails - 'string4: "123"\n' # fails - 'string5: \'bar\'\n' # fails - 'string6: !!str genericstring\n' - 'string7: !!str 456\n' - 'string8: !!str "quotedgenericstring"\n' - 'binary: !!binary binstring\n' - 'integer: !!int intstring\n' - 'boolean2: !!bool boolstring\n' - 'boolean3: !!bool "quotedboolstring"\n' - 'block-seq:\n' - ' - foo\n' - ' - "foo"\n' # fails - 'flow-seq: [foo, "foo"]\n' # fails - 'flow-map: {a: foo, b: "foo"}\n' # fails - 'flow-seq2: [foo, "foo,bar"]\n' # fails - 'flow-map2: {a: foo, b: "foo,bar"}\n' # fails - 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' - 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', - conf, problem1=(5, 10), problem2=(6, 10), problem3=(7, 10), - problem4=(8, 10), problem5=(18, 5), problem6=(19, 17), - problem7=(20, 23), problem8=(21, 18), problem9=(22, 24), - problem10=(23, 33), problem11=(24, 30), problem12=(24, 45)) - self.check('---\n' - 'multiline string 1: |\n' - ' line 1\n' - ' line 2\n' - 'multiline string 2: >\n' - ' word 1\n' - ' word 2\n' - 'multiline string 3:\n' - ' word 1\n' - ' word 2\n' - 'multiline string 4:\n' - ' "word 1\\\n' # fails - ' word 2"\n', - conf, problem1=(12, 3)) + conf = ( + 'quoted-strings: {quote-type: single,\n' + ' required: only-when-needed}\n' + ) + + self.check( + '---\n' + 'boolean1: true\n' + 'number1: 123\n' + 'string1: foo\n' + 'string2: "foo"\n' # fails + 'string3: "true"\n' # fails + 'string4: "123"\n' # fails + "string5: 'bar'\n" # fails + 'string6: !!str genericstring\n' + 'string7: !!str 456\n' + 'string8: !!str "quotedgenericstring"\n' + 'binary: !!binary binstring\n' + 'integer: !!int intstring\n' + 'boolean2: !!bool boolstring\n' + 'boolean3: !!bool "quotedboolstring"\n' + 'block-seq:\n' + ' - foo\n' + ' - "foo"\n' # fails + 'flow-seq: [foo, "foo"]\n' # fails + 'flow-map: {a: foo, b: "foo"}\n' # fails + 'flow-seq2: [foo, "foo,bar"]\n' # fails + 'flow-map2: {a: foo, b: "foo,bar"}\n' # fails + 'nested-flow1: {a: foo, b: [foo, "foo,bar"]}\n' + 'nested-flow2: [{a: foo}, {b: "foo,bar", c: ["d[e]"]}]\n', + conf, + problem1=(5, 10), + problem2=(6, 10), + problem3=(7, 10), + problem4=(8, 10), + problem5=(18, 5), + problem6=(19, 17), + problem7=(20, 23), + problem8=(21, 18), + problem9=(22, 24), + problem10=(23, 33), + problem11=(24, 30), + problem12=(24, 45), + ) + self.check( + '---\n' + 'multiline string 1: |\n' + ' line 1\n' + ' line 2\n' + 'multiline string 2: >\n' + ' word 1\n' + ' word 2\n' + 'multiline string 3:\n' + ' word 1\n' + ' word 2\n' + 'multiline string 4:\n' + ' "word 1\\\n' # fails + ' word 2"\n', + conf, + problem1=(12, 3), + ) def test_only_when_needed_corner_cases(self): conf = 'quoted-strings: {required: only-when-needed}\n' - self.check('---\n' - '- ""\n' - '- "- item"\n' - '- "key: value"\n' - '- "%H:%M:%S"\n' - '- "%wheel ALL=(ALL) NOPASSWD: ALL"\n' - '- \'"quoted"\'\n' - '- "\'foo\' == \'bar\'"\n' - '- "\'Mac\' in ansible_facts.product_name"\n' - '- \'foo # bar\'\n', - conf) - self.check('---\n' - 'k1: ""\n' - 'k2: "- item"\n' - 'k3: "key: value"\n' - 'k4: "%H:%M:%S"\n' - 'k5: "%wheel ALL=(ALL) NOPASSWD: ALL"\n' - 'k6: \'"quoted"\'\n' - 'k7: "\'foo\' == \'bar\'"\n' - 'k8: "\'Mac\' in ansible_facts.product_name"\n', - conf) - - self.check('---\n' - '- ---\n' - '- "---"\n' # fails - '- ----------\n' - '- "----------"\n' # fails - '- :wq\n' - '- ":wq"\n', # fails - conf, problem1=(3, 3), problem2=(5, 3), problem3=(7, 3)) - self.check('---\n' - 'k1: ---\n' - 'k2: "---"\n' # fails - 'k3: ----------\n' - 'k4: "----------"\n' # fails - 'k5: :wq\n' - 'k6: ":wq"\n', # fails - conf, problem1=(3, 5), problem2=(5, 5), problem3=(7, 5)) + self.check( + '---\n' + '- ""\n' + '- "- item"\n' + '- "key: value"\n' + '- "%H:%M:%S"\n' + '- "%wheel ALL=(ALL) NOPASSWD: ALL"\n' + '- \'"quoted"\'\n' + "- \"'foo' == 'bar'\"\n" + '- "\'Mac\' in ansible_facts.product_name"\n' + "- 'foo # bar'\n", + conf, + ) + self.check( + '---\n' + 'k1: ""\n' + 'k2: "- item"\n' + 'k3: "key: value"\n' + 'k4: "%H:%M:%S"\n' + 'k5: "%wheel ALL=(ALL) NOPASSWD: ALL"\n' + 'k6: \'"quoted"\'\n' + "k7: \"'foo' == 'bar'\"\n" + 'k8: "\'Mac\' in ansible_facts.product_name"\n', + conf, + ) + + self.check( + '---\n' + '- ---\n' + '- "---"\n' # fails + '- ----------\n' + '- "----------"\n' # fails + '- :wq\n' + '- ":wq"\n', # fails + conf, + problem1=(3, 3), + problem2=(5, 3), + problem3=(7, 3), + ) + self.check( + '---\n' + 'k1: ---\n' + 'k2: "---"\n' # fails + 'k3: ----------\n' + 'k4: "----------"\n' # fails + 'k5: :wq\n' + 'k6: ":wq"\n', # fails + conf, + problem1=(3, 5), + problem2=(5, 5), + problem3=(7, 5), + ) def test_only_when_needed_extras(self): - conf = ('quoted-strings:\n' - ' required: true\n' - ' extra-allowed: [^http://]\n') + conf = 'quoted-strings:\n' ' required: true\n' ' extra-allowed: [^http://]\n' self.assertRaises(config.YamlLintConfigError, self.check, '', conf) - conf = ('quoted-strings:\n' - ' required: true\n' - ' extra-required: [^http://]\n') + conf = 'quoted-strings:\n' ' required: true\n' ' extra-required: [^http://]\n' self.assertRaises(config.YamlLintConfigError, self.check, '', conf) - conf = ('quoted-strings:\n' - ' required: false\n' - ' extra-allowed: [^http://]\n') + conf = 'quoted-strings:\n' ' required: false\n' ' extra-allowed: [^http://]\n' self.assertRaises(config.YamlLintConfigError, self.check, '', conf) - conf = ('quoted-strings:\n' - ' required: true\n') - self.check('---\n' - '- 123\n' - '- "123"\n' - '- localhost\n' # fails - '- "localhost"\n' - '- http://localhost\n' # fails - '- "http://localhost"\n' - '- ftp://localhost\n' # fails - '- "ftp://localhost"\n', - conf, problem1=(4, 3), problem2=(6, 3), problem3=(8, 3)) - - conf = ('quoted-strings:\n' - ' required: only-when-needed\n' - ' extra-allowed: [^ftp://]\n' - ' extra-required: [^http://]\n') - self.check('---\n' - '- 123\n' - '- "123"\n' - '- localhost\n' - '- "localhost"\n' # fails - '- http://localhost\n' # fails - '- "http://localhost"\n' - '- ftp://localhost\n' - '- "ftp://localhost"\n', - conf, problem1=(5, 3), problem2=(6, 3)) - - conf = ('quoted-strings:\n' - ' required: false\n' - ' extra-required: [^http://, ^ftp://]\n') - self.check('---\n' - '- 123\n' - '- "123"\n' - '- localhost\n' - '- "localhost"\n' - '- http://localhost\n' # fails - '- "http://localhost"\n' - '- ftp://localhost\n' # fails - '- "ftp://localhost"\n', - conf, problem1=(6, 3), problem2=(8, 3)) - - conf = ('quoted-strings:\n' - ' required: only-when-needed\n' - ' extra-allowed: [^ftp://, ";$", " "]\n') - self.check('---\n' - '- localhost\n' - '- "localhost"\n' # fails - '- ftp://localhost\n' - '- "ftp://localhost"\n' - '- i=i+1\n' - '- "i=i+1"\n' # fails - '- i=i+2;\n' - '- "i=i+2;"\n' - '- foo\n' - '- "foo"\n' # fails - '- foo bar\n' - '- "foo bar"\n', - conf, problem1=(3, 3), problem2=(7, 3), problem3=(11, 3)) + conf = 'quoted-strings:\n' ' required: true\n' + self.check( + '---\n' + '- 123\n' + '- "123"\n' + '- localhost\n' # fails + '- "localhost"\n' + '- http://localhost\n' # fails + '- "http://localhost"\n' + '- ftp://localhost\n' # fails + '- "ftp://localhost"\n', + conf, + problem1=(4, 3), + problem2=(6, 3), + problem3=(8, 3), + ) + + conf = ( + 'quoted-strings:\n' + ' required: only-when-needed\n' + ' extra-allowed: [^ftp://]\n' + ' extra-required: [^http://]\n' + ) + self.check( + '---\n' + '- 123\n' + '- "123"\n' + '- localhost\n' + '- "localhost"\n' # fails + '- http://localhost\n' # fails + '- "http://localhost"\n' + '- ftp://localhost\n' + '- "ftp://localhost"\n', + conf, + problem1=(5, 3), + problem2=(6, 3), + ) + + conf = ( + 'quoted-strings:\n' + ' required: false\n' + ' extra-required: [^http://, ^ftp://]\n' + ) + self.check( + '---\n' + '- 123\n' + '- "123"\n' + '- localhost\n' + '- "localhost"\n' + '- http://localhost\n' # fails + '- "http://localhost"\n' + '- ftp://localhost\n' # fails + '- "ftp://localhost"\n', + conf, + problem1=(6, 3), + problem2=(8, 3), + ) + + conf = ( + 'quoted-strings:\n' + ' required: only-when-needed\n' + ' extra-allowed: [^ftp://, ";$", " "]\n' + ) + self.check( + '---\n' + '- localhost\n' + '- "localhost"\n' # fails + '- ftp://localhost\n' + '- "ftp://localhost"\n' + '- i=i+1\n' + '- "i=i+1"\n' # fails + '- i=i+2;\n' + '- "i=i+2;"\n' + '- foo\n' + '- "foo"\n' # fails + '- foo bar\n' + '- "foo bar"\n', + conf, + problem1=(3, 3), + problem2=(7, 3), + problem3=(11, 3), + ) def test_octal_values(self): conf = 'quoted-strings: {required: true}\n' - self.check('---\n' - '- 100\n' - '- 0100\n' - '- 0o100\n' - '- 777\n' - '- 0777\n' - '- 0o777\n' - '- 800\n' - '- 0800\n' - '- 0o800\n' - '- "0800"\n' - '- "0o800"\n', - conf, - problem1=(9, 3), problem2=(10, 3)) + self.check( + '---\n' + '- 100\n' + '- 0100\n' + '- 0o100\n' + '- 777\n' + '- 0777\n' + '- 0o777\n' + '- 800\n' + '- 0800\n' + '- 0o800\n' + '- "0800"\n' + '- "0o800"\n', + conf, + problem1=(9, 3), + problem2=(10, 3), + ) def test_allow_quoted_quotes(self): - conf = ('quoted-strings: {quote-type: single,\n' - ' required: false,\n' - ' allow-quoted-quotes: false}\n') - self.check('---\n' - 'foo1: "[barbaz]"\n' # fails - 'foo2: "[bar\'baz]"\n', # fails - conf, problem1=(2, 7), problem2=(3, 7)) - - conf = ('quoted-strings: {quote-type: single,\n' - ' required: false,\n' - ' allow-quoted-quotes: true}\n') - self.check('---\n' - 'foo1: "[barbaz]"\n' # fails - 'foo2: "[bar\'baz]"\n', - conf, problem1=(2, 7)) - - conf = ('quoted-strings: {quote-type: single,\n' - ' required: true,\n' - ' allow-quoted-quotes: false}\n') - self.check('---\n' - 'foo1: "[barbaz]"\n' # fails - 'foo2: "[bar\'baz]"\n', # fails - conf, problem1=(2, 7), problem2=(3, 7)) - - conf = ('quoted-strings: {quote-type: single,\n' - ' required: true,\n' - ' allow-quoted-quotes: true}\n') - self.check('---\n' - 'foo1: "[barbaz]"\n' # fails - 'foo2: "[bar\'baz]"\n', - conf, problem1=(2, 7)) - - conf = ('quoted-strings: {quote-type: single,\n' - ' required: only-when-needed,\n' - ' allow-quoted-quotes: false}\n') - self.check('---\n' - 'foo1: "[barbaz]"\n' # fails - 'foo2: "[bar\'baz]"\n', # fails - conf, problem1=(2, 7), problem2=(3, 7)) - - conf = ('quoted-strings: {quote-type: single,\n' - ' required: only-when-needed,\n' - ' allow-quoted-quotes: true}\n') - self.check('---\n' - 'foo1: "[barbaz]"\n' # fails - 'foo2: "[bar\'baz]"\n', - conf, problem1=(2, 7)) - - conf = ('quoted-strings: {quote-type: double,\n' - ' required: false,\n' - ' allow-quoted-quotes: false}\n') - self.check("---\n" - "foo1: '[barbaz]'\n" # fails - "foo2: '[bar\"baz]'\n", # fails - conf, problem1=(2, 7), problem2=(3, 7)) - - conf = ('quoted-strings: {quote-type: double,\n' - ' required: false,\n' - ' allow-quoted-quotes: true}\n') - self.check("---\n" - "foo1: '[barbaz]'\n" # fails - "foo2: '[bar\"baz]'\n", - conf, problem1=(2, 7)) - - conf = ('quoted-strings: {quote-type: double,\n' - ' required: true,\n' - ' allow-quoted-quotes: false}\n') - self.check("---\n" - "foo1: '[barbaz]'\n" # fails - "foo2: '[bar\"baz]'\n", # fails - conf, problem1=(2, 7), problem2=(3, 7)) - - conf = ('quoted-strings: {quote-type: double,\n' - ' required: true,\n' - ' allow-quoted-quotes: true}\n') - self.check("---\n" - "foo1: '[barbaz]'\n" # fails - "foo2: '[bar\"baz]'\n", - conf, problem1=(2, 7)) - - conf = ('quoted-strings: {quote-type: double,\n' - ' required: only-when-needed,\n' - ' allow-quoted-quotes: false}\n') - self.check("---\n" - "foo1: '[barbaz]'\n" # fails - "foo2: '[bar\"baz]'\n", # fails - conf, problem1=(2, 7), problem2=(3, 7)) - - conf = ('quoted-strings: {quote-type: double,\n' - ' required: only-when-needed,\n' - ' allow-quoted-quotes: true}\n') - self.check("---\n" - "foo1: '[barbaz]'\n" # fails - "foo2: '[bar\"baz]'\n", - conf, problem1=(2, 7)) - - conf = ('quoted-strings: {quote-type: any}\n') - self.check("---\n" - "foo1: '[barbaz]'\n" - "foo2: '[bar\"baz]'\n", - conf) + conf = ( + 'quoted-strings: {quote-type: single,\n' + ' required: false,\n' + ' allow-quoted-quotes: false}\n' + ) + self.check( + '---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', # fails + conf, + problem1=(2, 7), + problem2=(3, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: single,\n' + ' required: false,\n' + ' allow-quoted-quotes: true}\n' + ) + self.check( + '---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', + conf, + problem1=(2, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: single,\n' + ' required: true,\n' + ' allow-quoted-quotes: false}\n' + ) + self.check( + '---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', # fails + conf, + problem1=(2, 7), + problem2=(3, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: single,\n' + ' required: true,\n' + ' allow-quoted-quotes: true}\n' + ) + self.check( + '---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', + conf, + problem1=(2, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: single,\n' + ' required: only-when-needed,\n' + ' allow-quoted-quotes: false}\n' + ) + self.check( + '---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', # fails + conf, + problem1=(2, 7), + problem2=(3, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: single,\n' + ' required: only-when-needed,\n' + ' allow-quoted-quotes: true}\n' + ) + self.check( + '---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', + conf, + problem1=(2, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: double,\n' + ' required: false,\n' + ' allow-quoted-quotes: false}\n' + ) + self.check( + '---\n' + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", # fails + conf, + problem1=(2, 7), + problem2=(3, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: double,\n' + ' required: false,\n' + ' allow-quoted-quotes: true}\n' + ) + self.check( + '---\n' + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", + conf, + problem1=(2, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: double,\n' + ' required: true,\n' + ' allow-quoted-quotes: false}\n' + ) + self.check( + '---\n' + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", # fails + conf, + problem1=(2, 7), + problem2=(3, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: double,\n' + ' required: true,\n' + ' allow-quoted-quotes: true}\n' + ) + self.check( + '---\n' + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", + conf, + problem1=(2, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: double,\n' + ' required: only-when-needed,\n' + ' allow-quoted-quotes: false}\n' + ) + self.check( + '---\n' + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", # fails + conf, + problem1=(2, 7), + problem2=(3, 7), + ) + + conf = ( + 'quoted-strings: {quote-type: double,\n' + ' required: only-when-needed,\n' + ' allow-quoted-quotes: true}\n' + ) + self.check( + '---\n' + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", + conf, + problem1=(2, 7), + ) + + conf = 'quoted-strings: {quote-type: any}\n' + self.check('---\n' "foo1: '[barbaz]'\n" "foo2: '[bar\"baz]'\n", conf) class QuotedKeysTestCase(RuleTestCase): rule_id = 'quoted-strings' def test_disabled(self): - conf_disabled = "quoted-strings: {}" - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') + conf_disabled = 'quoted-strings: {}' + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) self.check(key_strings, conf_disabled) def test_default(self): # Default configuration, but with check-keys - conf_default = ("quoted-strings:\n" - " check-keys: true\n") - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') - self.check(key_strings, conf_default, problem1=(4, 1), - problem3=(20, 3), problem4=(23, 2), problem5=(33, 3)) + conf_default = 'quoted-strings:\n' ' check-keys: true\n' + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) + self.check( + key_strings, + conf_default, + problem1=(4, 1), + problem3=(20, 3), + problem4=(23, 2), + problem5=(33, 3), + ) def test_quote_type_any(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: any\n') - - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') - self.check(key_strings, conf, - problem1=(4, 1), problem2=(20, 3), problem3=(23, 2), - problem4=(33, 3)) + conf = 'quoted-strings:\n' ' check-keys: true\n' ' quote-type: any\n' + + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) + self.check( + key_strings, + conf, + problem1=(4, 1), + problem2=(20, 3), + problem3=(23, 2), + problem4=(33, 3), + ) def test_quote_type_single(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n') - - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') - self.check(key_strings, conf, - problem1=(4, 1), problem2=(5, 1), problem3=(6, 1), - problem4=(7, 1), problem5=(20, 3), problem6=(21, 3), - problem7=(23, 2), problem8=(23, 10), problem9=(33, 3), - problem10=(37, 3)) + conf = 'quoted-strings:\n' ' check-keys: true\n' ' quote-type: single\n' + + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) + self.check( + key_strings, + conf, + problem1=(4, 1), + problem2=(5, 1), + problem3=(6, 1), + problem4=(7, 1), + problem5=(20, 3), + problem6=(21, 3), + problem7=(23, 2), + problem8=(23, 10), + problem9=(33, 3), + problem10=(37, 3), + ) def test_quote_type_double(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: double\n') - - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') - self.check(key_strings, conf, - problem1=(4, 1), problem2=(8, 1), problem3=(20, 3), - problem4=(23, 2), problem5=(33, 3)) + conf = 'quoted-strings:\n' ' check-keys: true\n' ' quote-type: double\n' + + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) + self.check( + key_strings, + conf, + problem1=(4, 1), + problem2=(8, 1), + problem3=(20, 3), + problem4=(23, 2), + problem5=(33, 3), + ) def test_any_quotes_not_required(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: any\n' - ' required: false\n') - - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: any\n' + ' required: false\n' + ) + + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) self.check(key_strings, conf) def test_single_quotes_not_required(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n' - ' required: false\n') - - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') - self.check(key_strings, conf, - problem1=(5, 1), problem2=(6, 1), problem3=(7, 1), - problem4=(21, 3), problem5=(23, 10), problem6=(37, 3)) + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: single\n' + ' required: false\n' + ) + + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) + self.check( + key_strings, + conf, + problem1=(5, 1), + problem2=(6, 1), + problem3=(7, 1), + problem4=(21, 3), + problem5=(23, 10), + problem6=(37, 3), + ) def test_only_when_needed(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: only-when-needed\n') - - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') - self.check(key_strings, conf, - problem1=(5, 1), problem2=(8, 1), problem3=(21, 3), - problem4=(23, 10), problem5=(37, 3)) + conf = ( + 'quoted-strings:\n' ' check-keys: true\n' ' required: only-when-needed\n' + ) + + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) + self.check( + key_strings, + conf, + problem1=(5, 1), + problem2=(8, 1), + problem3=(21, 3), + problem4=(23, 10), + problem5=(37, 3), + ) def test_only_when_needed_single_quotes(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n' - ' required: only-when-needed\n') - - key_strings = ('---\n' - 'true: 2\n' - '123: 3\n' - 'foo1: 4\n' - '"foo2": 5\n' - '"false": 6\n' - '"234": 7\n' - '\'bar\': 8\n' - '!!str generic_string: 9\n' - '!!str 456: 10\n' - '!!str "quoted_generic_string": 11\n' - '!!binary binstring: 12\n' - '!!int int_string: 13\n' - '!!bool bool_string: 14\n' - '!!bool "quoted_bool_string": 15\n' - # Sequences and mappings - '? - 16\n' - ' - 17\n' - ': 18\n' - '[119, 219]: 19\n' - '? a: 20\n' - ' "b": 21\n' - ': 22\n' - '{a: 123, "b": 223}: 23\n' - # Multiline strings - '? |\n' - ' line 1\n' - ' line 2\n' - ': 27\n' - '? >\n' - ' line 1\n' - ' line 2\n' - ': 31\n' - '?\n' - ' line 1\n' - ' line 2\n' - ': 35\n' - '?\n' - ' "line 1\\\n' - ' line 2"\n' - ': 39\n') - self.check(key_strings, conf, - problem1=(5, 1), problem2=(6, 1), problem3=(7, 1), - problem4=(8, 1), problem5=(21, 3), problem6=(23, 10), - problem7=(37, 3)) + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: single\n' + ' required: only-when-needed\n' + ) + + key_strings = ( + '---\n' + 'true: 2\n' + '123: 3\n' + 'foo1: 4\n' + '"foo2": 5\n' + '"false": 6\n' + '"234": 7\n' + "'bar': 8\n" + '!!str generic_string: 9\n' + '!!str 456: 10\n' + '!!str "quoted_generic_string": 11\n' + '!!binary binstring: 12\n' + '!!int int_string: 13\n' + '!!bool bool_string: 14\n' + '!!bool "quoted_bool_string": 15\n' + # Sequences and mappings + '? - 16\n' + ' - 17\n' + ': 18\n' + '[119, 219]: 19\n' + '? a: 20\n' + ' "b": 21\n' + ': 22\n' + '{a: 123, "b": 223}: 23\n' + # Multiline strings + '? |\n' + ' line 1\n' + ' line 2\n' + ': 27\n' + '? >\n' + ' line 1\n' + ' line 2\n' + ': 31\n' + '?\n' + ' line 1\n' + ' line 2\n' + ': 35\n' + '?\n' + ' "line 1\\\n' + ' line 2"\n' + ': 39\n' + ) + self.check( + key_strings, + conf, + problem1=(5, 1), + problem2=(6, 1), + problem3=(7, 1), + problem4=(8, 1), + problem5=(21, 3), + problem6=(23, 10), + problem7=(37, 3), + ) def test_only_when_needed_corner_cases(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: only-when-needed\n') - - self.check('---\n' - '"": 2\n' - '"- item": 3\n' - '"key: value": 4\n' - '"%H:%M:%S": 5\n' - '"%wheel ALL=(ALL) NOPASSWD: ALL": 6\n' - '\'"quoted"\': 7\n' - '"\'foo\' == \'bar\'": 8\n' - '"\'Mac\' in ansible_facts.product_name": 9\n' - '\'foo # bar\': 10\n', - conf) - self.check('---\n' - '"": 2\n' - '"- item": 3\n' - '"key: value": 4\n' - '"%H:%M:%S": 5\n' - '"%wheel ALL=(ALL) NOPASSWD: ALL": 6\n' - '\'"quoted"\': 7\n' - '"\'foo\' == \'bar\'": 8\n' - '"\'Mac\' in ansible_facts.product_name": 9\n', - conf) - - self.check('---\n' - '---: 2\n' - '"----": 3\n' # fails - '---------: 4\n' - '"----------": 5\n' # fails - ':wq: 6\n' - '":cw": 7\n', # fails - conf, problem1=(3, 1), problem2=(5, 1), problem3=(7, 1)) + conf = ( + 'quoted-strings:\n' ' check-keys: true\n' ' required: only-when-needed\n' + ) + + self.check( + '---\n' + '"": 2\n' + '"- item": 3\n' + '"key: value": 4\n' + '"%H:%M:%S": 5\n' + '"%wheel ALL=(ALL) NOPASSWD: ALL": 6\n' + '\'"quoted"\': 7\n' + "\"'foo' == 'bar'\": 8\n" + '"\'Mac\' in ansible_facts.product_name": 9\n' + "'foo # bar': 10\n", + conf, + ) + self.check( + '---\n' + '"": 2\n' + '"- item": 3\n' + '"key: value": 4\n' + '"%H:%M:%S": 5\n' + '"%wheel ALL=(ALL) NOPASSWD: ALL": 6\n' + '\'"quoted"\': 7\n' + "\"'foo' == 'bar'\": 8\n" + '"\'Mac\' in ansible_facts.product_name": 9\n', + conf, + ) + + self.check( + '---\n' + '---: 2\n' + '"----": 3\n' # fails + '---------: 4\n' + '"----------": 5\n' # fails + ':wq: 6\n' + '":cw": 7\n', # fails + conf, + problem1=(3, 1), + problem2=(5, 1), + problem3=(7, 1), + ) def test_only_when_needed_extras(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: true\n' - ' extra-allowed: [^http://]\n') + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' required: true\n' + ' extra-allowed: [^http://]\n' + ) self.assertRaises(config.YamlLintConfigError, self.check, '', conf) - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: true\n' - ' extra-required: [^http://]\n') + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' required: true\n' + ' extra-required: [^http://]\n' + ) self.assertRaises(config.YamlLintConfigError, self.check, '', conf) - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: false\n' - ' extra-allowed: [^http://]\n') + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' required: false\n' + ' extra-allowed: [^http://]\n' + ) self.assertRaises(config.YamlLintConfigError, self.check, '', conf) - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: true\n') - self.check('---\n' - '123: 2\n' - '"234": 3\n' - 'localhost: 4\n' # fails - '"host.local": 5\n' - 'http://localhost: 6\n' # fails - '"http://host.local": 7\n' - 'ftp://localhost: 8\n' # fails - '"ftp://host.local": 9\n', - conf, problem1=(4, 1), problem2=(6, 1), problem3=(8, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: only-when-needed\n' - ' extra-allowed: [^ftp://]\n' - ' extra-required: [^http://]\n') - self.check('---\n' - '123: 2\n' - '"234": 3\n' - 'localhost: 4\n' - '"host.local": 5\n' # fails - 'http://localhost: 6\n' # fails - '"http://host.local": 7\n' - 'ftp://localhost: 8\n' - '"ftp://host.local": 9\n', - conf, problem1=(5, 1), problem2=(6, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: false\n' - ' extra-required: [^http://, ^ftp://]\n') - self.check('---\n' - '123: 2\n' - '"234": 3\n' - 'localhost: 4\n' - '"host.local": 5\n' - 'http://localhost: 6\n' # fails - '"http://host.local": 7\n' - 'ftp://localhost: 8\n' # fails - '"ftp://host.local": 9\n', - conf, problem1=(6, 1), problem2=(8, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: only-when-needed\n' - ' extra-allowed: [^ftp://, ";$", " "]\n') - self.check('---\n' - 'localhost: 2\n' - '"host.local": 3\n' # fails - 'ftp://localhost: 4\n' - '"ftp://host.local": 5\n' - 'i=i+1: 6\n' - '"i=i+2": 7\n' # fails - 'i=i+3;: 8\n' - '"i=i+4;": 9\n' - 'foo1: 10\n' - '"foo2": 11\n' # fails - 'foo bar1: 12\n' - '"foo bar2": 13\n', - conf, problem1=(3, 1), problem2=(7, 1), problem3=(11, 1)) + conf = 'quoted-strings:\n' ' check-keys: true\n' ' required: true\n' + self.check( + '---\n' + '123: 2\n' + '"234": 3\n' + 'localhost: 4\n' # fails + '"host.local": 5\n' + 'http://localhost: 6\n' # fails + '"http://host.local": 7\n' + 'ftp://localhost: 8\n' # fails + '"ftp://host.local": 9\n', + conf, + problem1=(4, 1), + problem2=(6, 1), + problem3=(8, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' required: only-when-needed\n' + ' extra-allowed: [^ftp://]\n' + ' extra-required: [^http://]\n' + ) + self.check( + '---\n' + '123: 2\n' + '"234": 3\n' + 'localhost: 4\n' + '"host.local": 5\n' # fails + 'http://localhost: 6\n' # fails + '"http://host.local": 7\n' + 'ftp://localhost: 8\n' + '"ftp://host.local": 9\n', + conf, + problem1=(5, 1), + problem2=(6, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' required: false\n' + ' extra-required: [^http://, ^ftp://]\n' + ) + self.check( + '---\n' + '123: 2\n' + '"234": 3\n' + 'localhost: 4\n' + '"host.local": 5\n' + 'http://localhost: 6\n' # fails + '"http://host.local": 7\n' + 'ftp://localhost: 8\n' # fails + '"ftp://host.local": 9\n', + conf, + problem1=(6, 1), + problem2=(8, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' required: only-when-needed\n' + ' extra-allowed: [^ftp://, ";$", " "]\n' + ) + self.check( + '---\n' + 'localhost: 2\n' + '"host.local": 3\n' # fails + 'ftp://localhost: 4\n' + '"ftp://host.local": 5\n' + 'i=i+1: 6\n' + '"i=i+2": 7\n' # fails + 'i=i+3;: 8\n' + '"i=i+4;": 9\n' + 'foo1: 10\n' + '"foo2": 11\n' # fails + 'foo bar1: 12\n' + '"foo bar2": 13\n', + conf, + problem1=(3, 1), + problem2=(7, 1), + problem3=(11, 1), + ) def test_octal_values(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' required: true\n') - - self.check('---\n' - '100: 2\n' - '0100: 3\n' - '0o100: 4\n' - '777: 5\n' - '0777: 6\n' - '0o777: 7\n' - '800: 8\n' - '0800: 9\n' # fails - '0o800: 10\n' # fails - '"0900": 11\n' - '"0o900": 12\n', - conf, - problem1=(9, 1), problem2=(10, 1)) + conf = 'quoted-strings:\n' ' check-keys: true\n' ' required: true\n' + + self.check( + '---\n' + '100: 2\n' + '0100: 3\n' + '0o100: 4\n' + '777: 5\n' + '0777: 6\n' + '0o777: 7\n' + '800: 8\n' + '0800: 9\n' # fails + '0o800: 10\n' # fails + '"0900": 11\n' + '"0o900": 12\n', + conf, + problem1=(9, 1), + problem2=(10, 1), + ) def test_allow_quoted_quotes(self): - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n' - ' required: false\n' - ' allow-quoted-quotes: false\n') - self.check('---\n' - '"[barbaz]": 2\n' # fails - '"[bar\'baz]": 3\n', # fails - conf, problem1=(2, 1), problem2=(3, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n' - ' required: false\n' - ' allow-quoted-quotes: true\n') - self.check('---\n' - '"[barbaz]": 2\n' # fails - '"[bar\'baz]": 3\n', - conf, problem1=(2, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n' - ' required: true\n' - ' allow-quoted-quotes: false\n') - self.check('---\n' - '"[barbaz]": 2\n' # fails - '"[bar\'baz]": 3\n', # fails - conf, problem1=(2, 1), problem2=(3, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n' - ' required: true\n' - ' allow-quoted-quotes: true\n') - self.check('---\n' - '"[barbaz]": 2\n' # fails - '"[bar\'baz]": 3\n', - conf, problem1=(2, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n' - ' required: only-when-needed\n' - ' allow-quoted-quotes: false\n') - self.check('---\n' - '"[barbaz]": 2\n' # fails - '"[bar\'baz]": 3\n', # fails - conf, problem1=(2, 1), problem2=(3, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: single\n' - ' required: only-when-needed\n' - ' allow-quoted-quotes: true\n') - self.check('---\n' - '"[barbaz]": 2\n' # fails - '"[bar\'baz]": 3\n', - conf, problem1=(2, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: double\n' - ' required: false\n' - ' allow-quoted-quotes: false\n') - self.check("---\n" - "'[barbaz]': 2\n" # fails - "'[bar\"baz]': 3\n", # fails - conf, problem1=(2, 1), problem2=(3, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: double\n' - ' required: false\n' - ' allow-quoted-quotes: true\n') - self.check("---\n" - "'[barbaz]': 2\n" # fails - "'[bar\"baz]': 3\n", - conf, problem1=(2, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: double\n' - ' required: true\n' - ' allow-quoted-quotes: false\n') - self.check("---\n" - "'[barbaz]': 2\n" # fails - "'[bar\"baz]': 3\n", # fails - conf, problem1=(2, 1), problem2=(3, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: double\n' - ' required: true\n' - ' allow-quoted-quotes: true\n') - self.check("---\n" - "'[barbaz]': 2\n" # fails - "'[bar\"baz]': 3\n", - conf, problem1=(2, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: double\n' - ' required: only-when-needed\n' - ' allow-quoted-quotes: false\n') - self.check("---\n" - "'[barbaz]': 2\n" # fails - "'[bar\"baz]': 3\n", # fails - conf, problem1=(2, 1), problem2=(3, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: double\n' - ' required: only-when-needed\n' - ' allow-quoted-quotes: true\n') - self.check("---\n" - "'[barbaz]': 2\n" # fails - "'[bar\"baz]': 3\n", - conf, problem1=(2, 1)) - - conf = ('quoted-strings:\n' - ' check-keys: true\n' - ' quote-type: any\n') - self.check("---\n" - "'[barbaz]': 2\n" - "'[bar\"baz]': 3\n", - conf) + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: single\n' + ' required: false\n' + ' allow-quoted-quotes: false\n' + ) + self.check( + '---\n' + '"[barbaz]": 2\n' # fails + '"[bar\'baz]": 3\n', # fails + conf, + problem1=(2, 1), + problem2=(3, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: single\n' + ' required: false\n' + ' allow-quoted-quotes: true\n' + ) + self.check( + '---\n' + '"[barbaz]": 2\n' # fails + '"[bar\'baz]": 3\n', + conf, + problem1=(2, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: single\n' + ' required: true\n' + ' allow-quoted-quotes: false\n' + ) + self.check( + '---\n' + '"[barbaz]": 2\n' # fails + '"[bar\'baz]": 3\n', # fails + conf, + problem1=(2, 1), + problem2=(3, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: single\n' + ' required: true\n' + ' allow-quoted-quotes: true\n' + ) + self.check( + '---\n' + '"[barbaz]": 2\n' # fails + '"[bar\'baz]": 3\n', + conf, + problem1=(2, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: single\n' + ' required: only-when-needed\n' + ' allow-quoted-quotes: false\n' + ) + self.check( + '---\n' + '"[barbaz]": 2\n' # fails + '"[bar\'baz]": 3\n', # fails + conf, + problem1=(2, 1), + problem2=(3, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: single\n' + ' required: only-when-needed\n' + ' allow-quoted-quotes: true\n' + ) + self.check( + '---\n' + '"[barbaz]": 2\n' # fails + '"[bar\'baz]": 3\n', + conf, + problem1=(2, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: double\n' + ' required: false\n' + ' allow-quoted-quotes: false\n' + ) + self.check( + '---\n' + "'[barbaz]': 2\n" # fails + "'[bar\"baz]': 3\n", # fails + conf, + problem1=(2, 1), + problem2=(3, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: double\n' + ' required: false\n' + ' allow-quoted-quotes: true\n' + ) + self.check( + '---\n' + "'[barbaz]': 2\n" # fails + "'[bar\"baz]': 3\n", + conf, + problem1=(2, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: double\n' + ' required: true\n' + ' allow-quoted-quotes: false\n' + ) + self.check( + '---\n' + "'[barbaz]': 2\n" # fails + "'[bar\"baz]': 3\n", # fails + conf, + problem1=(2, 1), + problem2=(3, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: double\n' + ' required: true\n' + ' allow-quoted-quotes: true\n' + ) + self.check( + '---\n' + "'[barbaz]': 2\n" # fails + "'[bar\"baz]': 3\n", + conf, + problem1=(2, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: double\n' + ' required: only-when-needed\n' + ' allow-quoted-quotes: false\n' + ) + self.check( + '---\n' + "'[barbaz]': 2\n" # fails + "'[bar\"baz]': 3\n", # fails + conf, + problem1=(2, 1), + problem2=(3, 1), + ) + + conf = ( + 'quoted-strings:\n' + ' check-keys: true\n' + ' quote-type: double\n' + ' required: only-when-needed\n' + ' allow-quoted-quotes: true\n' + ) + self.check( + '---\n' + "'[barbaz]': 2\n" # fails + "'[bar\"baz]': 3\n", + conf, + problem1=(2, 1), + ) + + conf = 'quoted-strings:\n' ' check-keys: true\n' ' quote-type: any\n' + self.check('---\n' "'[barbaz]': 2\n" "'[bar\"baz]': 3\n", conf) diff --git a/tests/rules/test_trailing_spaces.py b/tests/rules/test_trailing_spaces.py index 016f56ef..e469400d 100644 --- a/tests/rules/test_trailing_spaces.py +++ b/tests/rules/test_trailing_spaces.py @@ -24,8 +24,7 @@ def test_disabled(self): self.check('', conf) self.check('\n', conf) self.check(' \n', conf) - self.check('---\n' - 'some: text \n', conf) + self.check('---\n' 'some: text \n', conf) def test_enabled(self): conf = 'trailing-spaces: enable' @@ -33,15 +32,10 @@ def test_enabled(self): self.check('\n', conf) self.check(' \n', conf, problem=(1, 1)) self.check('\t\t\t\n', conf, problem=(1, 1, 'syntax')) - self.check('---\n' - 'some: text \n', conf, problem=(2, 11)) - self.check('---\n' - 'some: text\t\n', conf, problem=(2, 11, 'syntax')) + self.check('---\n' 'some: text \n', conf, problem=(2, 11)) + self.check('---\n' 'some: text\t\n', conf, problem=(2, 11, 'syntax')) def test_with_dos_new_lines(self): - conf = ('trailing-spaces: enable\n' - 'new-lines: {type: dos}\n') - self.check('---\r\n' - 'some: text\r\n', conf) - self.check('---\r\n' - 'some: text \r\n', conf, problem=(2, 11)) + conf = 'trailing-spaces: enable\n' 'new-lines: {type: dos}\n' + self.check('---\r\n' 'some: text\r\n', conf) + self.check('---\r\n' 'some: text \r\n', conf, problem=(2, 11)) diff --git a/tests/rules/test_truthy.py b/tests/rules/test_truthy.py index c8c8b7a1..d9e230cf 100644 --- a/tests/rules/test_truthy.py +++ b/tests/rules/test_truthy.py @@ -21,125 +21,126 @@ class TruthyTestCase(RuleTestCase): def test_disabled(self): conf = 'truthy: disable' - self.check('---\n' - '1: True\n', conf) - self.check('---\n' - 'True: 1\n', conf) + self.check('---\n' '1: True\n', conf) + self.check('---\n' 'True: 1\n', conf) def test_enabled(self): conf = 'truthy: enable\n' - self.check('---\n' - '1: True\n' - 'True: 1\n', - conf, problem1=(2, 4), problem2=(3, 1)) - self.check('---\n' - '1: "True"\n' - '"True": 1\n', conf) - self.check('---\n' - '[\n' - ' true, false,\n' - ' "false", "FALSE",\n' - ' "true", "True",\n' - ' True, FALSE,\n' - ' on, OFF,\n' - ' NO, Yes\n' - ']\n', conf, - problem1=(6, 3), problem2=(6, 9), - problem3=(7, 3), problem4=(7, 7), - problem5=(8, 3), problem6=(8, 7)) + self.check( + '---\n' '1: True\n' 'True: 1\n', conf, problem1=(2, 4), problem2=(3, 1) + ) + self.check('---\n' '1: "True"\n' '"True": 1\n', conf) + self.check( + '---\n' + '[\n' + ' true, false,\n' + ' "false", "FALSE",\n' + ' "true", "True",\n' + ' True, FALSE,\n' + ' on, OFF,\n' + ' NO, Yes\n' + ']\n', + conf, + problem1=(6, 3), + problem2=(6, 9), + problem3=(7, 3), + problem4=(7, 7), + problem5=(8, 3), + problem6=(8, 7), + ) def test_different_allowed_values(self): - conf = ('truthy:\n' - ' allowed-values: ["yes", "no"]\n') - self.check('---\n' - 'key1: foo\n' - 'key2: yes\n' - 'key3: bar\n' - 'key4: no\n', conf) - self.check('---\n' - 'key1: true\n' - 'key2: Yes\n' - 'key3: false\n' - 'key4: no\n' - 'key5: yes\n', - conf, - problem1=(2, 7), problem2=(3, 7), - problem3=(4, 7)) + conf = 'truthy:\n' ' allowed-values: ["yes", "no"]\n' + self.check('---\n' 'key1: foo\n' 'key2: yes\n' 'key3: bar\n' 'key4: no\n', conf) + self.check( + '---\n' + 'key1: true\n' + 'key2: Yes\n' + 'key3: false\n' + 'key4: no\n' + 'key5: yes\n', + conf, + problem1=(2, 7), + problem2=(3, 7), + problem3=(4, 7), + ) def test_combined_allowed_values(self): - conf = ('truthy:\n' - ' allowed-values: ["yes", "no", "true", "false"]\n') - self.check('---\n' - 'key1: foo\n' - 'key2: yes\n' - 'key3: bar\n' - 'key4: no\n', conf) - self.check('---\n' - 'key1: true\n' - 'key2: Yes\n' - 'key3: false\n' - 'key4: no\n' - 'key5: yes\n', - conf, problem1=(3, 7)) + conf = 'truthy:\n' ' allowed-values: ["yes", "no", "true", "false"]\n' + self.check('---\n' 'key1: foo\n' 'key2: yes\n' 'key3: bar\n' 'key4: no\n', conf) + self.check( + '---\n' + 'key1: true\n' + 'key2: Yes\n' + 'key3: false\n' + 'key4: no\n' + 'key5: yes\n', + conf, + problem1=(3, 7), + ) def test_no_allowed_values(self): - conf = ('truthy:\n' - ' allowed-values: []\n') - self.check('---\n' - 'key1: foo\n' - 'key2: bar\n', conf) - self.check('---\n' - 'key1: true\n' - 'key2: yes\n' - 'key3: false\n' - 'key4: no\n', conf, - problem1=(2, 7), problem2=(3, 7), - problem3=(4, 7), problem4=(5, 7)) + conf = 'truthy:\n' ' allowed-values: []\n' + self.check('---\n' 'key1: foo\n' 'key2: bar\n', conf) + self.check( + '---\n' 'key1: true\n' 'key2: yes\n' 'key3: false\n' 'key4: no\n', + conf, + problem1=(2, 7), + problem2=(3, 7), + problem3=(4, 7), + problem4=(5, 7), + ) def test_explicit_types(self): conf = 'truthy: enable\n' - self.check('---\n' - 'string1: !!str True\n' - 'string2: !!str yes\n' - 'string3: !!str off\n' - 'encoded: !!binary |\n' - ' True\n' - ' OFF\n' - ' pad==\n' # this decodes as 'N\xbb\x9e8Qii' - 'boolean1: !!bool true\n' - 'boolean2: !!bool "false"\n' - 'boolean3: !!bool FALSE\n' - 'boolean4: !!bool True\n' - 'boolean5: !!bool off\n' - 'boolean6: !!bool NO\n', - conf) + self.check( + '---\n' + 'string1: !!str True\n' + 'string2: !!str yes\n' + 'string3: !!str off\n' + 'encoded: !!binary |\n' + ' True\n' + ' OFF\n' + ' pad==\n' # this decodes as 'N\xbb\x9e8Qii' + 'boolean1: !!bool true\n' + 'boolean2: !!bool "false"\n' + 'boolean3: !!bool FALSE\n' + 'boolean4: !!bool True\n' + 'boolean5: !!bool off\n' + 'boolean6: !!bool NO\n', + conf, + ) def test_check_keys_disabled(self): - conf = ('truthy:\n' - ' allowed-values: []\n' - ' check-keys: false\n' - 'key-duplicates: disable\n') - self.check('---\n' - 'YES: 0\n' - 'Yes: 0\n' - 'yes: 0\n' - 'No: 0\n' - 'No: 0\n' - 'no: 0\n' - 'TRUE: 0\n' - 'True: 0\n' - 'true: 0\n' - 'FALSE: 0\n' - 'False: 0\n' - 'false: 0\n' - 'ON: 0\n' - 'On: 0\n' - 'on: 0\n' - 'OFF: 0\n' - 'Off: 0\n' - 'off: 0\n' - 'YES:\n' - ' Yes:\n' - ' yes:\n' - ' on: 0\n', - conf) + conf = ( + 'truthy:\n' + ' allowed-values: []\n' + ' check-keys: false\n' + 'key-duplicates: disable\n' + ) + self.check( + '---\n' + 'YES: 0\n' + 'Yes: 0\n' + 'yes: 0\n' + 'No: 0\n' + 'No: 0\n' + 'no: 0\n' + 'TRUE: 0\n' + 'True: 0\n' + 'true: 0\n' + 'FALSE: 0\n' + 'False: 0\n' + 'false: 0\n' + 'ON: 0\n' + 'On: 0\n' + 'on: 0\n' + 'OFF: 0\n' + 'Off: 0\n' + 'off: 0\n' + 'YES:\n' + ' Yes:\n' + ' yes:\n' + ' on: 0\n', + conf, + ) diff --git a/tests/test_cli.py b/tests/test_cli.py index bcdd000b..be227e3c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -76,7 +76,7 @@ def setUpModule(): 'HOME', 'USERPROFILE', 'HOMEPATH', - 'HOMEDRIVE' + 'HOMEDRIVE', ) for name in env_vars_that_could_interfere: try: @@ -90,48 +90,42 @@ class CommandLineTestCase(unittest.TestCase): def setUpClass(cls): super().setUpClass() - cls.wd = build_temp_workspace({ - # .yaml file at root - 'a.yaml': '---\n' - '- 1 \n' - '- 2', - # file with only one warning - 'warn.yaml': 'key: value\n', - # .yml file at root - 'empty.yml': '', - # file in dir - 'sub/ok.yaml': '---\n' - 'key: value\n', - # directory that looks like a yaml file - 'sub/directory.yaml/not-yaml.txt': '', - 'sub/directory.yaml/empty.yml': '', - # file in very nested dir - 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml': '---\n' - 'key: value\n' - 'key: other value\n', - # empty dir - 'empty-dir': [], - # non-YAML file - 'no-yaml.json': '---\n' - 'key: value\n', - # non-ASCII chars - 'non-ascii/éçäγλνπ¥/utf-8': ( - '---\n' - '- hétérogénéité\n' - '# 19.99 €\n' - '- お早う御座います。\n' - '# الأَبْجَدِيَّة العَرَبِيَّة\n').encode(), - # dos line endings yaml - 'dos.yml': '---\r\n' - 'dos: true', - # different key-ordering by locale - 'c.yaml': '---\n' - 'A: true\n' - 'a: true', - 'en.yaml': '---\n' - 'a: true\n' - 'A: true' - }) + cls.wd = build_temp_workspace( + { + # .yaml file at root + 'a.yaml': '---\n' '- 1 \n' '- 2', + # file with only one warning + 'warn.yaml': 'key: value\n', + # .yml file at root + 'empty.yml': '', + # file in dir + 'sub/ok.yaml': '---\n' 'key: value\n', + # directory that looks like a yaml file + 'sub/directory.yaml/not-yaml.txt': '', + 'sub/directory.yaml/empty.yml': '', + # file in very nested dir + 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml': '---\n' + 'key: value\n' + 'key: other value\n', + # empty dir + 'empty-dir': [], + # non-YAML file + 'no-yaml.json': '---\n' 'key: value\n', + # non-ASCII chars + 'non-ascii/éçäγλνπ¥/utf-8': ( + '---\n' + '- hétérogénéité\n' + '# 19.99 €\n' + '- お早う御座います。\n' + '# الأَبْجَدِيَّة العَرَبِيَّة\n' + ).encode(), + # dos line endings yaml + 'dos.yml': '---\r\n' 'dos: true', + # different key-ordering by locale + 'c.yaml': '---\n' 'A: true\n' 'a: true', + 'en.yaml': '---\n' 'a: true\n' 'A: true', + } + ) @classmethod def tearDownClass(cls): @@ -143,119 +137,135 @@ def test_find_files_recursively(self): conf = config.YamlLintConfig('extends: default') self.assertEqual( sorted(cli.find_files_recursively([self.wd], conf)), - [os.path.join(self.wd, 'a.yaml'), - os.path.join(self.wd, 'c.yaml'), - os.path.join(self.wd, 'dos.yml'), - os.path.join(self.wd, 'empty.yml'), - os.path.join(self.wd, 'en.yaml'), - os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), - os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), - os.path.join(self.wd, 'sub/ok.yaml'), - os.path.join(self.wd, 'warn.yaml')], - ) - - items = [os.path.join(self.wd, 'sub/ok.yaml'), - os.path.join(self.wd, 'empty-dir')] + [ + os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 'c.yaml'), + os.path.join(self.wd, 'dos.yml'), + os.path.join(self.wd, 'empty.yml'), + os.path.join(self.wd, 'en.yaml'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml'), + ], + ) + + items = [ + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'empty-dir'), + ] self.assertEqual( sorted(cli.find_files_recursively(items, conf)), [os.path.join(self.wd, 'sub/ok.yaml')], ) - items = [os.path.join(self.wd, 'empty.yml'), - os.path.join(self.wd, 's')] + items = [os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's')] self.assertEqual( sorted(cli.find_files_recursively(items, conf)), - [os.path.join(self.wd, 'empty.yml'), - os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml')], + [ + os.path.join(self.wd, 'empty.yml'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + ], ) - items = [os.path.join(self.wd, 'sub'), - os.path.join(self.wd, '/etc/another/file')] + items = [ + os.path.join(self.wd, 'sub'), + os.path.join(self.wd, '/etc/another/file'), + ] self.assertEqual( sorted(cli.find_files_recursively(items, conf)), - [os.path.join(self.wd, '/etc/another/file'), - os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), - os.path.join(self.wd, 'sub/ok.yaml')], + [ + os.path.join(self.wd, '/etc/another/file'), + os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), + os.path.join(self.wd, 'sub/ok.yaml'), + ], ) - conf = config.YamlLintConfig('extends: default\n' - 'yaml-files:\n' - ' - \'*.yaml\' \n') + conf = config.YamlLintConfig( + 'extends: default\n' 'yaml-files:\n' " - '*.yaml' \n" + ) self.assertEqual( sorted(cli.find_files_recursively([self.wd], conf)), - [os.path.join(self.wd, 'a.yaml'), - os.path.join(self.wd, 'c.yaml'), - os.path.join(self.wd, 'en.yaml'), - os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), - os.path.join(self.wd, 'sub/ok.yaml'), - os.path.join(self.wd, 'warn.yaml')] + [ + os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 'c.yaml'), + os.path.join(self.wd, 'en.yaml'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml'), + ], ) - conf = config.YamlLintConfig('extends: default\n' - 'yaml-files:\n' - ' - \'*.yml\'\n') + conf = config.YamlLintConfig( + 'extends: default\n' 'yaml-files:\n' " - '*.yml'\n" + ) self.assertEqual( sorted(cli.find_files_recursively([self.wd], conf)), - [os.path.join(self.wd, 'dos.yml'), - os.path.join(self.wd, 'empty.yml'), - os.path.join(self.wd, 'sub/directory.yaml/empty.yml')] + [ + os.path.join(self.wd, 'dos.yml'), + os.path.join(self.wd, 'empty.yml'), + os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), + ], ) - conf = config.YamlLintConfig('extends: default\n' - 'yaml-files:\n' - ' - \'*.json\'\n') + conf = config.YamlLintConfig( + 'extends: default\n' 'yaml-files:\n' " - '*.json'\n" + ) self.assertEqual( sorted(cli.find_files_recursively([self.wd], conf)), - [os.path.join(self.wd, 'no-yaml.json')] + [os.path.join(self.wd, 'no-yaml.json')], ) - conf = config.YamlLintConfig('extends: default\n' - 'yaml-files:\n' - ' - \'*\'\n') + conf = config.YamlLintConfig('extends: default\n' 'yaml-files:\n' " - '*'\n") self.assertEqual( sorted(cli.find_files_recursively([self.wd], conf)), - [os.path.join(self.wd, 'a.yaml'), - os.path.join(self.wd, 'c.yaml'), - os.path.join(self.wd, 'dos.yml'), - os.path.join(self.wd, 'empty.yml'), - os.path.join(self.wd, 'en.yaml'), - os.path.join(self.wd, 'no-yaml.json'), - os.path.join(self.wd, 'non-ascii/éçäγλνπ¥/utf-8'), - os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), - os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), - os.path.join(self.wd, 'sub/directory.yaml/not-yaml.txt'), - os.path.join(self.wd, 'sub/ok.yaml'), - os.path.join(self.wd, 'warn.yaml')] - ) - - conf = config.YamlLintConfig('extends: default\n' - 'yaml-files:\n' - ' - \'*.yaml\'\n' - ' - \'*\'\n' - ' - \'**\'\n') + [ + os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 'c.yaml'), + os.path.join(self.wd, 'dos.yml'), + os.path.join(self.wd, 'empty.yml'), + os.path.join(self.wd, 'en.yaml'), + os.path.join(self.wd, 'no-yaml.json'), + os.path.join(self.wd, 'non-ascii/éçäγλνπ¥/utf-8'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), + os.path.join(self.wd, 'sub/directory.yaml/not-yaml.txt'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml'), + ], + ) + + conf = config.YamlLintConfig( + 'extends: default\n' + 'yaml-files:\n' + " - '*.yaml'\n" + " - '*'\n" + " - '**'\n" + ) self.assertEqual( sorted(cli.find_files_recursively([self.wd], conf)), - [os.path.join(self.wd, 'a.yaml'), - os.path.join(self.wd, 'c.yaml'), - os.path.join(self.wd, 'dos.yml'), - os.path.join(self.wd, 'empty.yml'), - os.path.join(self.wd, 'en.yaml'), - os.path.join(self.wd, 'no-yaml.json'), - os.path.join(self.wd, 'non-ascii/éçäγλνπ¥/utf-8'), - os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), - os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), - os.path.join(self.wd, 'sub/directory.yaml/not-yaml.txt'), - os.path.join(self.wd, 'sub/ok.yaml'), - os.path.join(self.wd, 'warn.yaml')] - ) - - conf = config.YamlLintConfig('extends: default\n' - 'yaml-files:\n' - ' - \'s/**\'\n' - ' - \'**/utf-8\'\n') + [ + os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 'c.yaml'), + os.path.join(self.wd, 'dos.yml'), + os.path.join(self.wd, 'empty.yml'), + os.path.join(self.wd, 'en.yaml'), + os.path.join(self.wd, 'no-yaml.json'), + os.path.join(self.wd, 'non-ascii/éçäγλνπ¥/utf-8'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), + os.path.join(self.wd, 'sub/directory.yaml/not-yaml.txt'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml'), + ], + ) + + conf = config.YamlLintConfig( + 'extends: default\n' 'yaml-files:\n' " - 's/**'\n" " - '**/utf-8'\n" + ) self.assertEqual( sorted(cli.find_files_recursively([self.wd], conf)), - [os.path.join(self.wd, 'non-ascii/éçäγλνπ¥/utf-8')] + [os.path.join(self.wd, 'non-ascii/éçäγλνπ¥/utf-8')], ) def test_run_with_bad_arguments(self): @@ -266,7 +276,7 @@ def test_run_with_bad_arguments(self): self.assertRegex(ctx.stderr, r'^usage') with RunContext(self) as ctx: - cli.run(('--unknown-arg', )) + cli.run(('--unknown-arg',)) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') self.assertRegex(ctx.stderr, r'^usage') @@ -278,7 +288,7 @@ def test_run_with_bad_arguments(self): self.assertRegex( ctx.stderr.splitlines()[-1], r'^yamllint: error: argument -d\/--config-data: ' - r'not allowed with argument -c\/--config-file$' + r'not allowed with argument -c\/--config-file$', ) # checks if reading from stdin and files are mutually exclusive @@ -307,10 +317,12 @@ def test_run_with_implicit_extends_config(self): with RunContext(self) as ctx: cli.run(('-d', 'default', '-f', 'parsable', path)) - expected_out = (f'{path}:1:1: [warning] missing document start "---" ' - f'(document-start)\n') + expected_out = ( + f'{path}:1:1: [warning] missing document start "---" ' f'(document-start)\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (0, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (0, expected_out, '') + ) def test_run_with_config_file(self): with open(os.path.join(self.wd, 'config'), 'w') as f: @@ -340,14 +352,14 @@ def test_run_with_user_global_config_file(self): f.write('rules: {trailing-spaces: disable}') with RunContext(self) as ctx: - cli.run((os.path.join(self.wd, 'a.yaml'), )) + cli.run((os.path.join(self.wd, 'a.yaml'),)) self.assertEqual(ctx.returncode, 0) with open(config, 'w') as f: f.write('rules: {trailing-spaces: enable}') with RunContext(self) as ctx: - cli.run((os.path.join(self.wd, 'a.yaml'), )) + cli.run((os.path.join(self.wd, 'a.yaml'),)) self.assertEqual(ctx.returncode, 1) def test_run_with_user_xdg_config_home_in_env(self): @@ -371,7 +383,7 @@ def test_run_with_user_yamllint_config_file_in_env(self): f.write('rules: {trailing-spaces: disable}') f.flush() with RunContext(self) as ctx: - cli.run((os.path.join(self.wd, 'a.yaml'), )) + cli.run((os.path.join(self.wd, 'a.yaml'),)) self.assertEqual(ctx.returncode, 0) with tempfile.NamedTemporaryFile('w') as f: @@ -379,7 +391,7 @@ def test_run_with_user_yamllint_config_file_in_env(self): f.write('rules: {trailing-spaces: enable}') f.flush() with RunContext(self) as ctx: - cli.run((os.path.join(self.wd, 'a.yaml'), )) + cli.run((os.path.join(self.wd, 'a.yaml'),)) self.assertEqual(ctx.returncode, 1) def test_run_with_locale(self): @@ -394,14 +406,24 @@ def test_run_with_locale(self): # C + en.yaml should fail with RunContext(self) as ctx: - cli.run(('-d', 'rules: { key-ordering: enable }', - os.path.join(self.wd, 'en.yaml'))) + cli.run( + ( + '-d', + 'rules: { key-ordering: enable }', + os.path.join(self.wd, 'en.yaml'), + ) + ) self.assertEqual(ctx.returncode, 1) # C + c.yaml should pass with RunContext(self) as ctx: - cli.run(('-d', 'rules: { key-ordering: enable }', - os.path.join(self.wd, 'c.yaml'))) + cli.run( + ( + '-d', + 'rules: { key-ordering: enable }', + os.path.join(self.wd, 'c.yaml'), + ) + ) self.assertEqual(ctx.returncode, 0) # the next two runs use setlocale() inside, @@ -410,21 +432,29 @@ def test_run_with_locale(self): # en_US + en.yaml should pass with RunContext(self) as ctx: - cli.run(('-d', 'locale: en_US.UTF-8\n' - 'rules: { key-ordering: enable }', - os.path.join(self.wd, 'en.yaml'))) + cli.run( + ( + '-d', + 'locale: en_US.UTF-8\n' 'rules: { key-ordering: enable }', + os.path.join(self.wd, 'en.yaml'), + ) + ) self.assertEqual(ctx.returncode, 0) # en_US + c.yaml should fail with RunContext(self) as ctx: - cli.run(('-d', 'locale: en_US.UTF-8\n' - 'rules: { key-ordering: enable }', - os.path.join(self.wd, 'c.yaml'))) + cli.run( + ( + '-d', + 'locale: en_US.UTF-8\n' 'rules: { key-ordering: enable }', + os.path.join(self.wd, 'c.yaml'), + ) + ) self.assertEqual(ctx.returncode, 1) def test_run_version(self): with RunContext(self) as ctx: - cli.run(('--version', )) + cli.run(('--version',)) self.assertEqual(ctx.returncode, 0) self.assertRegex(ctx.stdout + ctx.stderr, r'yamllint \d+\.\d+') @@ -443,10 +473,14 @@ def test_run_one_problem_file(self): with RunContext(self) as ctx: cli.run(('-f', 'parsable', path)) self.assertEqual(ctx.returncode, 1) - self.assertEqual(ctx.stdout, ( - f'{path}:2:4: [error] trailing spaces (trailing-spaces)\n' - f'{path}:3:4: [error] no new line character at the end of file ' - f'(new-line-at-end-of-file)\n')) + self.assertEqual( + ctx.stdout, + ( + f'{path}:2:4: [error] trailing spaces (trailing-spaces)\n' + f'{path}:3:4: [error] no new line character at the end of file ' + f'(new-line-at-end-of-file)\n' + ), + ) self.assertEqual(ctx.stderr, '') def test_run_one_warning(self): @@ -488,29 +522,36 @@ def test_run_non_ascii_file(self): self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (0, '', '')) def test_run_multiple_files(self): - items = [os.path.join(self.wd, 'empty.yml'), - os.path.join(self.wd, 's')] + items = [os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's')] path = items[1] + '/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml' with RunContext(self) as ctx: cli.run(['-f', 'parsable'] + items) self.assertEqual((ctx.returncode, ctx.stderr), (1, '')) - self.assertEqual(ctx.stdout, ( - f'{path}:3:1: [error] duplication of key "key" in mapping ' - f'(key-duplicates)\n')) + self.assertEqual( + ctx.stdout, + ( + f'{path}:3:1: [error] duplication of key "key" in mapping ' + f'(key-duplicates)\n' + ), + ) def test_run_piped_output_nocolor(self): path = os.path.join(self.wd, 'a.yaml') with RunContext(self) as ctx: - cli.run((path, )) + cli.run((path,)) self.assertEqual((ctx.returncode, ctx.stderr), (1, '')) - self.assertEqual(ctx.stdout, ( - f'{path}\n' - f' 2:4 error trailing spaces (trailing-spaces)\n' - f' 3:4 error no new line character at the end of file ' - f'(new-line-at-end-of-file)\n' - f'\n')) + self.assertEqual( + ctx.stdout, + ( + f'{path}\n' + f' 2:4 error trailing spaces (trailing-spaces)\n' + f' 3:4 error no new line character at the end of file ' + f'(new-line-at-end-of-file)\n' + f'\n' + ), + ) def test_run_default_format_output_in_tty(self): path = os.path.join(self.wd, 'a.yaml') @@ -520,7 +561,7 @@ def test_run_default_format_output_in_tty(self): sys.stdout = sys.stderr = os.fdopen(slave, 'w') with self.assertRaises(SystemExit) as ctx: - cli.run((path, )) + cli.run((path,)) sys.stdout.flush() self.assertEqual(ctx.exception.code, 1) @@ -536,28 +577,34 @@ def test_run_default_format_output_in_tty(self): sys.stderr.close() output.close() - self.assertEqual(out, ( - f'\033[4m{path}\033[0m\n' - f' \033[2m2:4\033[0m \033[31merror\033[0m ' - f'trailing spaces \033[2m(trailing-spaces)\033[0m\n' - f' \033[2m3:4\033[0m \033[31merror\033[0m ' - f'no new line character at the end of file ' - f'\033[2m(new-line-at-end-of-file)\033[0m\n' - f'\n')) + self.assertEqual( + out, + ( + f'\033[4m{path}\033[0m\n' + f' \033[2m2:4\033[0m \033[31merror\033[0m ' + f'trailing spaces \033[2m(trailing-spaces)\033[0m\n' + f' \033[2m3:4\033[0m \033[31merror\033[0m ' + f'no new line character at the end of file ' + f'\033[2m(new-line-at-end-of-file)\033[0m\n' + f'\n' + ), + ) def test_run_default_format_output_without_tty(self): path = os.path.join(self.wd, 'a.yaml') with RunContext(self) as ctx: - cli.run((path, )) + cli.run((path,)) expected_out = ( f'{path}\n' f' 2:4 error trailing spaces (trailing-spaces)\n' f' 3:4 error no new line character at the end of file ' f'(new-line-at-end-of-file)\n' - f'\n') + f'\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '') + ) def test_run_auto_output_without_tty_output(self): path = os.path.join(self.wd, 'a.yaml') @@ -569,9 +616,11 @@ def test_run_auto_output_without_tty_output(self): f' 2:4 error trailing spaces (trailing-spaces)\n' f' 3:4 error no new line character at the end of file ' f'(new-line-at-end-of-file)\n' - f'\n') + f'\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '') + ) def test_run_format_colored(self): path = os.path.join(self.wd, 'a.yaml') @@ -585,9 +634,11 @@ def test_run_format_colored(self): f' \033[2m3:4\033[0m \033[31merror\033[0m ' f'no new line character at the end of file ' f'\033[2m(new-line-at-end-of-file)\033[0m\n' - f'\n') + f'\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '') + ) def test_run_format_colored_warning(self): path = os.path.join(self.wd, 'warn.yaml') @@ -598,9 +649,11 @@ def test_run_format_colored_warning(self): f'\033[4m{path}\033[0m\n' f' \033[2m1:1\033[0m \033[33mwarning\033[0m ' f'missing document start "---" \033[2m(document-start)\033[0m\n' - f'\n') + f'\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (0, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (0, expected_out, '') + ) def test_run_format_github(self): path = os.path.join(self.wd, 'a.yaml') @@ -613,9 +666,11 @@ def test_run_format_github(self): f' spaces\n' f'::error file={path},line=3,col=4::3:4 [new-line-at-end-of-file]' f' no new line character at the end of file\n' - f'::endgroup::\n\n') + f'::endgroup::\n\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '') + ) def test_github_actions_detection(self): path = os.path.join(self.wd, 'a.yaml') @@ -625,32 +680,34 @@ def test_github_actions_detection(self): with RunContext(self) as ctx: os.environ['GITHUB_ACTIONS'] = 'something' os.environ['GITHUB_WORKFLOW'] = 'something' - cli.run((path, )) + cli.run((path,)) expected_out = ( f'::group::{path}\n' f'::error file={path},line=2,col=4::2:4 [trailing-spaces] trailing' f' spaces\n' f'::error file={path},line=3,col=4::3:4 [new-line-at-end-of-file]' f' no new line character at the end of file\n' - f'::endgroup::\n\n') + f'::endgroup::\n\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '') + ) def test_run_read_from_stdin(self): # prepares stdin with an invalid yaml string so that we can check # for its specific error, and be assured that stdin was read self.addCleanup(setattr, sys, 'stdin', sys.__stdin__) - sys.stdin = StringIO( - 'I am a string\n' - 'therefore: I am an error\n') + sys.stdin = StringIO('I am a string\n' 'therefore: I am an error\n') with RunContext(self) as ctx: cli.run(('-', '-f', 'parsable')) expected_out = ( 'stdin:2:10: [error] syntax error: ' - 'mapping values are not allowed here (syntax)\n') + 'mapping values are not allowed here (syntax)\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '') + ) def test_run_no_warnings(self): path = os.path.join(self.wd, 'a.yaml') @@ -662,9 +719,11 @@ def test_run_no_warnings(self): f' 2:4 error trailing spaces (trailing-spaces)\n' f' 3:4 error no new line character at the end of file ' f'(new-line-at-end-of-file)\n' - f'\n') + f'\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '') + ) path = os.path.join(self.wd, 'warn.yaml') @@ -692,9 +751,11 @@ def test_run_non_universal_newline(self): f'{path}\n' f' 1:4 error wrong new line character: expected \\n' f' (new-lines)\n' - f'\n') + f'\n' + ) self.assertEqual( - (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) + (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '') + ) def test_run_list_files(self): with RunContext(self) as ctx: @@ -702,15 +763,17 @@ def test_run_list_files(self): self.assertEqual(ctx.returncode, 0) self.assertEqual( sorted(ctx.stdout.splitlines()), - [os.path.join(self.wd, 'a.yaml'), - os.path.join(self.wd, 'c.yaml'), - os.path.join(self.wd, 'dos.yml'), - os.path.join(self.wd, 'empty.yml'), - os.path.join(self.wd, 'en.yaml'), - os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), - os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), - os.path.join(self.wd, 'sub/ok.yaml'), - os.path.join(self.wd, 'warn.yaml')] + [ + os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 'c.yaml'), + os.path.join(self.wd, 'dos.yml'), + os.path.join(self.wd, 'empty.yml'), + os.path.join(self.wd, 'en.yaml'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml'), + ], ) config = '{ignore: "*.yml", yaml-files: ["*.*"]}' @@ -719,22 +782,23 @@ def test_run_list_files(self): self.assertEqual(ctx.returncode, 0) self.assertEqual( sorted(ctx.stdout.splitlines()), - [os.path.join(self.wd, 'a.yaml'), - os.path.join(self.wd, 'c.yaml'), - os.path.join(self.wd, 'en.yaml'), - os.path.join(self.wd, 'no-yaml.json'), - os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), - os.path.join(self.wd, 'sub/directory.yaml/not-yaml.txt'), - os.path.join(self.wd, 'sub/ok.yaml'), - os.path.join(self.wd, 'warn.yaml')] + [ + os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 'c.yaml'), + os.path.join(self.wd, 'en.yaml'), + os.path.join(self.wd, 'no-yaml.json'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/directory.yaml/not-yaml.txt'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml'), + ], ) class CommandLineConfigTestCase(unittest.TestCase): def test_config_file(self): workspace = {'a.yml': 'hello: world\n'} - conf = ('---\n' - 'extends: relaxed\n') + conf = '---\n' 'extends: relaxed\n' for conf_file in ('.yamllint', '.yamllint.yml', '.yamllint.yaml'): with self.subTest(conf_file): @@ -742,21 +806,25 @@ def test_config_file(self): with RunContext(self) as ctx: cli.run(('-f', 'parsable', '.')) - self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), - (0, './a.yml:1:1: [warning] missing document ' - 'start "---" (document-start)\n', '')) + self.assertEqual( + (ctx.returncode, ctx.stdout, ctx.stderr), + ( + 0, + './a.yml:1:1: [warning] missing document ' + 'start "---" (document-start)\n', + '', + ), + ) with temp_workspace({**workspace, **{conf_file: conf}}): with RunContext(self) as ctx: cli.run(('-f', 'parsable', '.')) - self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), - (0, '', '')) + self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (0, '', '')) def test_parent_config_file(self): workspace = {'a/b/c/d/e/f/g/a.yml': 'hello: world\n'} - conf = ('---\n' - 'extends: relaxed\n') + conf = '---\n' 'extends: relaxed\n' for conf_file in ('.yamllint', '.yamllint.yml', '.yamllint.yaml'): with self.subTest(conf_file): @@ -765,51 +833,64 @@ def test_parent_config_file(self): os.chdir('a/b/c/d/e/f') cli.run(('-f', 'parsable', '.')) - self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), - (0, './g/a.yml:1:1: [warning] missing ' - 'document start "---" (document-start)\n', - '')) + self.assertEqual( + (ctx.returncode, ctx.stdout, ctx.stderr), + ( + 0, + './g/a.yml:1:1: [warning] missing ' + 'document start "---" (document-start)\n', + '', + ), + ) with temp_workspace({**workspace, **{conf_file: conf}}): with RunContext(self) as ctx: os.chdir('a/b/c/d/e/f') cli.run(('-f', 'parsable', '.')) - self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), - (0, '', '')) + self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (0, '', '')) def test_multiple_parent_config_file(self): - workspace = {'a/b/c/3spaces.yml': 'array:\n' - ' - item\n', - 'a/b/c/4spaces.yml': 'array:\n' - ' - item\n', - 'a/.yamllint': '---\n' - 'extends: relaxed\n' - 'rules:\n' - ' indentation:\n' - ' spaces: 4\n', - } - - conf3 = ('---\n' - 'extends: relaxed\n' - 'rules:\n' - ' indentation:\n' - ' spaces: 3\n') + workspace = { + 'a/b/c/3spaces.yml': 'array:\n' ' - item\n', + 'a/b/c/4spaces.yml': 'array:\n' ' - item\n', + 'a/.yamllint': '---\n' + 'extends: relaxed\n' + 'rules:\n' + ' indentation:\n' + ' spaces: 4\n', + } + + conf3 = ( + '---\n' 'extends: relaxed\n' 'rules:\n' ' indentation:\n' ' spaces: 3\n' + ) with temp_workspace(workspace): with RunContext(self) as ctx: os.chdir('a/b/c') cli.run(('-f', 'parsable', '.')) - self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), - (0, './3spaces.yml:2:4: [warning] wrong indentation: ' - 'expected 4 but found 3 (indentation)\n', '')) + self.assertEqual( + (ctx.returncode, ctx.stdout, ctx.stderr), + ( + 0, + './3spaces.yml:2:4: [warning] wrong indentation: ' + 'expected 4 but found 3 (indentation)\n', + '', + ), + ) with temp_workspace({**workspace, **{'a/b/.yamllint.yml': conf3}}): with RunContext(self) as ctx: os.chdir('a/b/c') cli.run(('-f', 'parsable', '.')) - self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), - (0, './4spaces.yml:2:5: [warning] wrong indentation: ' - 'expected 3 but found 4 (indentation)\n', '')) + self.assertEqual( + (ctx.returncode, ctx.stdout, ctx.stderr), + ( + 0, + './4spaces.yml:2:5: [warning] wrong indentation: ' + 'expected 3 but found 4 (indentation)\n', + '', + ), + ) diff --git a/tests/test_config.py b/tests/test_config.py index 73f7c01e..5c7add73 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -28,10 +28,12 @@ class SimpleConfigTestCase(unittest.TestCase): def test_parse_config(self): - new = config.YamlLintConfig('rules:\n' - ' colons:\n' - ' max-spaces-before: 0\n' - ' max-spaces-after: 1\n') + new = config.YamlLintConfig( + 'rules:\n' + ' colons:\n' + ' max-spaces-before: 0\n' + ' max-spaces-after: 1\n' + ) self.assertEqual(list(new.rules.keys()), ['colons']) self.assertEqual(new.rules['colons']['max-spaces-before'], 0) @@ -45,79 +47,85 @@ def test_invalid_conf(self): def test_unknown_rule(self): with self.assertRaisesRegex( - config.YamlLintConfigError, - 'invalid config: no such rule: "this-one-does-not-exist"'): - config.YamlLintConfig('rules:\n' - ' this-one-does-not-exist: enable\n') + config.YamlLintConfigError, + 'invalid config: no such rule: "this-one-does-not-exist"', + ): + config.YamlLintConfig('rules:\n' ' this-one-does-not-exist: enable\n') def test_missing_option(self): - c = config.YamlLintConfig('rules:\n' - ' colons: enable\n') + c = config.YamlLintConfig('rules:\n' ' colons: enable\n') self.assertEqual(c.rules['colons']['max-spaces-before'], 0) self.assertEqual(c.rules['colons']['max-spaces-after'], 1) - c = config.YamlLintConfig('rules:\n' - ' colons:\n' - ' max-spaces-before: 9\n') + c = config.YamlLintConfig('rules:\n' ' colons:\n' ' max-spaces-before: 9\n') self.assertEqual(c.rules['colons']['max-spaces-before'], 9) self.assertEqual(c.rules['colons']['max-spaces-after'], 1) def test_unknown_option(self): with self.assertRaisesRegex( - config.YamlLintConfigError, - 'invalid config: unknown option "abcdef" for rule "colons"'): - config.YamlLintConfig('rules:\n' - ' colons:\n' - ' max-spaces-before: 0\n' - ' max-spaces-after: 1\n' - ' abcdef: yes\n') + config.YamlLintConfigError, + 'invalid config: unknown option "abcdef" for rule "colons"', + ): + config.YamlLintConfig( + 'rules:\n' + ' colons:\n' + ' max-spaces-before: 0\n' + ' max-spaces-after: 1\n' + ' abcdef: yes\n' + ) def test_yes_no_for_booleans(self): - c = config.YamlLintConfig('rules:\n' - ' indentation:\n' - ' spaces: 2\n' - ' indent-sequences: true\n' - ' check-multi-line-strings: false\n') + c = config.YamlLintConfig( + 'rules:\n' + ' indentation:\n' + ' spaces: 2\n' + ' indent-sequences: true\n' + ' check-multi-line-strings: false\n' + ) self.assertTrue(c.rules['indentation']['indent-sequences']) - self.assertEqual(c.rules['indentation']['check-multi-line-strings'], - False) - - c = config.YamlLintConfig('rules:\n' - ' indentation:\n' - ' spaces: 2\n' - ' indent-sequences: yes\n' - ' check-multi-line-strings: false\n') + self.assertEqual(c.rules['indentation']['check-multi-line-strings'], False) + + c = config.YamlLintConfig( + 'rules:\n' + ' indentation:\n' + ' spaces: 2\n' + ' indent-sequences: yes\n' + ' check-multi-line-strings: false\n' + ) self.assertTrue(c.rules['indentation']['indent-sequences']) - self.assertEqual(c.rules['indentation']['check-multi-line-strings'], - False) - - c = config.YamlLintConfig('rules:\n' - ' indentation:\n' - ' spaces: 2\n' - ' indent-sequences: whatever\n' - ' check-multi-line-strings: false\n') - self.assertEqual(c.rules['indentation']['indent-sequences'], - 'whatever') - self.assertEqual(c.rules['indentation']['check-multi-line-strings'], - False) + self.assertEqual(c.rules['indentation']['check-multi-line-strings'], False) + + c = config.YamlLintConfig( + 'rules:\n' + ' indentation:\n' + ' spaces: 2\n' + ' indent-sequences: whatever\n' + ' check-multi-line-strings: false\n' + ) + self.assertEqual(c.rules['indentation']['indent-sequences'], 'whatever') + self.assertEqual(c.rules['indentation']['check-multi-line-strings'], False) with self.assertRaisesRegex( - config.YamlLintConfigError, - 'invalid config: option "indent-sequences" of "indentation" ' - 'should be in '): - c = config.YamlLintConfig('rules:\n' - ' indentation:\n' - ' spaces: 2\n' - ' indent-sequences: YES!\n' - ' check-multi-line-strings: false\n') + config.YamlLintConfigError, + 'invalid config: option "indent-sequences" of "indentation" ' + 'should be in ', + ): + c = config.YamlLintConfig( + 'rules:\n' + ' indentation:\n' + ' spaces: 2\n' + ' indent-sequences: YES!\n' + ' check-multi-line-strings: false\n' + ) def test_enable_disable_keywords(self): - c = config.YamlLintConfig('rules:\n' - ' colons: enable\n' - ' hyphens: disable\n') - self.assertEqual(c.rules['colons'], {'level': 'error', - 'max-spaces-after': 1, - 'max-spaces-before': 0}) + c = config.YamlLintConfig( + 'rules:\n' ' colons: enable\n' ' hyphens: disable\n' + ) + self.assertEqual( + c.rules['colons'], + {'level': 'error', 'max-spaces-after': 1, 'max-spaces-before': 0}, + ) self.assertEqual(c.rules['hyphens'], False) def test_validate_rule_conf(self): @@ -125,50 +133,75 @@ class Rule: ID = 'fake' self.assertFalse(config.validate_rule_conf(Rule, False)) - self.assertEqual(config.validate_rule_conf(Rule, {}), - {'level': 'error'}) + self.assertEqual(config.validate_rule_conf(Rule, {}), {'level': 'error'}) config.validate_rule_conf(Rule, {'level': 'error'}) config.validate_rule_conf(Rule, {'level': 'warning'}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, {'level': 'warn'}) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'level': 'warn'}, + ) Rule.CONF = {'length': int} Rule.DEFAULT = {'length': 80} config.validate_rule_conf(Rule, {'length': 8}) config.validate_rule_conf(Rule, {}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, {'height': 8}) + self.assertRaises( + config.YamlLintConfigError, config.validate_rule_conf, Rule, {'height': 8} + ) Rule.CONF = {'a': bool, 'b': int} Rule.DEFAULT = {'a': True, 'b': -42} config.validate_rule_conf(Rule, {'a': True, 'b': 0}) config.validate_rule_conf(Rule, {'a': True}) config.validate_rule_conf(Rule, {'b': 0}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, {'a': 1, 'b': 0}) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'a': 1, 'b': 0}, + ) Rule.CONF = {'choice': (True, 88, 'str')} Rule.DEFAULT = {'choice': 88} config.validate_rule_conf(Rule, {'choice': True}) config.validate_rule_conf(Rule, {'choice': 88}) config.validate_rule_conf(Rule, {'choice': 'str'}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, {'choice': False}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, {'choice': 99}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, {'choice': 'abc'}) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'choice': False}, + ) + self.assertRaises( + config.YamlLintConfigError, config.validate_rule_conf, Rule, {'choice': 99} + ) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'choice': 'abc'}, + ) Rule.CONF = {'choice': (int, 'hardcoded')} Rule.DEFAULT = {'choice': 1337} config.validate_rule_conf(Rule, {'choice': 42}) config.validate_rule_conf(Rule, {'choice': 'hardcoded'}) config.validate_rule_conf(Rule, {}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, {'choice': False}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, {'choice': 'abc'}) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'choice': False}, + ) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'choice': 'abc'}, + ) Rule.CONF = {'multiple': ['item1', 'item2', 'item3']} Rule.DEFAULT = {'multiple': ['item1']} @@ -176,72 +209,85 @@ class Rule: config.validate_rule_conf(Rule, {'multiple': ['item2']}) config.validate_rule_conf(Rule, {'multiple': ['item2', 'item3']}) config.validate_rule_conf(Rule, {}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, - {'multiple': 'item1'}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, - {'multiple': ['']}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, - {'multiple': ['item1', 4]}) - self.assertRaises(config.YamlLintConfigError, - config.validate_rule_conf, Rule, - {'multiple': ['item4']}) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'multiple': 'item1'}, + ) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'multiple': ['']}, + ) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'multiple': ['item1', 4]}, + ) + self.assertRaises( + config.YamlLintConfigError, + config.validate_rule_conf, + Rule, + {'multiple': ['item4']}, + ) def test_invalid_rule(self): with self.assertRaisesRegex( - config.YamlLintConfigError, - 'invalid config: rule "colons": should be either ' - '"enable", "disable" or a dict'): - config.YamlLintConfig('rules:\n' - ' colons: invalid\n') + config.YamlLintConfigError, + 'invalid config: rule "colons": should be either ' + '"enable", "disable" or a dict', + ): + config.YamlLintConfig('rules:\n' ' colons: invalid\n') def test_invalid_ignore(self): with self.assertRaisesRegex( - config.YamlLintConfigError, - 'invalid config: ignore should contain file patterns'): + config.YamlLintConfigError, + 'invalid config: ignore should contain file patterns', + ): config.YamlLintConfig('ignore: yes\n') def test_invalid_rule_ignore(self): with self.assertRaisesRegex( - config.YamlLintConfigError, - 'invalid config: ignore should contain file patterns'): - config.YamlLintConfig('rules:\n' - ' colons:\n' - ' ignore: yes\n') + config.YamlLintConfigError, + 'invalid config: ignore should contain file patterns', + ): + config.YamlLintConfig('rules:\n' ' colons:\n' ' ignore: yes\n') def test_invalid_rule_ignore_from_file(self): self.assertRaises( config.YamlLintConfigError, config.YamlLintConfig, - 'rules:\n' - ' colons:\n' - ' ignore-from-file: 1337\n') + 'rules:\n' ' colons:\n' ' ignore-from-file: 1337\n', + ) def test_invalid_locale(self): with self.assertRaisesRegex( - config.YamlLintConfigError, - 'invalid config: locale should be a string'): + config.YamlLintConfigError, 'invalid config: locale should be a string' + ): config.YamlLintConfig('locale: yes\n') def test_invalid_yaml_files(self): with self.assertRaisesRegex( - config.YamlLintConfigError, - 'invalid config: yaml-files should be a list of file ' - 'patterns'): + config.YamlLintConfigError, + 'invalid config: yaml-files should be a list of file ' 'patterns', + ): config.YamlLintConfig('yaml-files: yes\n') class ExtendedConfigTestCase(unittest.TestCase): def test_extend_on_object(self): - old = config.YamlLintConfig('rules:\n' - ' colons:\n' - ' max-spaces-before: 0\n' - ' max-spaces-after: 1\n') - new = config.YamlLintConfig('rules:\n' - ' hyphens:\n' - ' max-spaces-after: 2\n') + old = config.YamlLintConfig( + 'rules:\n' + ' colons:\n' + ' max-spaces-before: 0\n' + ' max-spaces-after: 1\n' + ) + new = config.YamlLintConfig( + 'rules:\n' ' hyphens:\n' ' max-spaces-after: 2\n' + ) new.extend(old) self.assertEqual(sorted(new.rules.keys()), ['colons', 'hyphens']) @@ -253,15 +299,19 @@ def test_extend_on_object(self): def test_extend_on_file(self): with tempfile.NamedTemporaryFile('w') as f: - f.write('rules:\n' - ' colons:\n' - ' max-spaces-before: 0\n' - ' max-spaces-after: 1\n') + f.write( + 'rules:\n' + ' colons:\n' + ' max-spaces-before: 0\n' + ' max-spaces-after: 1\n' + ) f.flush() - c = config.YamlLintConfig('extends: ' + f.name + '\n' - 'rules:\n' - ' hyphens:\n' - ' max-spaces-after: 2\n') + c = config.YamlLintConfig( + 'extends: ' + f.name + '\n' + 'rules:\n' + ' hyphens:\n' + ' max-spaces-after: 2\n' + ) self.assertEqual(sorted(c.rules.keys()), ['colons', 'hyphens']) self.assertEqual(c.rules['colons']['max-spaces-before'], 0) @@ -272,16 +322,18 @@ def test_extend_on_file(self): def test_extend_remove_rule(self): with tempfile.NamedTemporaryFile('w') as f: - f.write('rules:\n' - ' colons:\n' - ' max-spaces-before: 0\n' - ' max-spaces-after: 1\n' - ' hyphens:\n' - ' max-spaces-after: 2\n') + f.write( + 'rules:\n' + ' colons:\n' + ' max-spaces-before: 0\n' + ' max-spaces-after: 1\n' + ' hyphens:\n' + ' max-spaces-after: 2\n' + ) f.flush() - c = config.YamlLintConfig('extends: ' + f.name + '\n' - 'rules:\n' - ' colons: disable\n') + c = config.YamlLintConfig( + 'extends: ' + f.name + '\n' 'rules:\n' ' colons: disable\n' + ) self.assertEqual(sorted(c.rules.keys()), ['colons', 'hyphens']) self.assertFalse(c.rules['colons']) @@ -291,18 +343,22 @@ def test_extend_remove_rule(self): def test_extend_edit_rule(self): with tempfile.NamedTemporaryFile('w') as f: - f.write('rules:\n' - ' colons:\n' - ' max-spaces-before: 0\n' - ' max-spaces-after: 1\n' - ' hyphens:\n' - ' max-spaces-after: 2\n') + f.write( + 'rules:\n' + ' colons:\n' + ' max-spaces-before: 0\n' + ' max-spaces-after: 1\n' + ' hyphens:\n' + ' max-spaces-after: 2\n' + ) f.flush() - c = config.YamlLintConfig('extends: ' + f.name + '\n' - 'rules:\n' - ' colons:\n' - ' max-spaces-before: 3\n' - ' max-spaces-after: 4\n') + c = config.YamlLintConfig( + 'extends: ' + f.name + '\n' + 'rules:\n' + ' colons:\n' + ' max-spaces-before: 3\n' + ' max-spaces-after: 4\n' + ) self.assertEqual(sorted(c.rules.keys()), ['colons', 'hyphens']) self.assertEqual(c.rules['colons']['max-spaces-before'], 3) @@ -313,16 +369,20 @@ def test_extend_edit_rule(self): def test_extend_reenable_rule(self): with tempfile.NamedTemporaryFile('w') as f: - f.write('rules:\n' - ' colons:\n' - ' max-spaces-before: 0\n' - ' max-spaces-after: 1\n' - ' hyphens: disable\n') + f.write( + 'rules:\n' + ' colons:\n' + ' max-spaces-before: 0\n' + ' max-spaces-after: 1\n' + ' hyphens: disable\n' + ) f.flush() - c = config.YamlLintConfig('extends: ' + f.name + '\n' - 'rules:\n' - ' hyphens:\n' - ' max-spaces-after: 2\n') + c = config.YamlLintConfig( + 'extends: ' + f.name + '\n' + 'rules:\n' + ' hyphens:\n' + ' max-spaces-after: 2\n' + ) self.assertEqual(sorted(c.rules.keys()), ['colons', 'hyphens']) self.assertEqual(c.rules['colons']['max-spaces-before'], 0) @@ -333,14 +393,14 @@ def test_extend_reenable_rule(self): def test_extend_recursive_default_values(self): with tempfile.NamedTemporaryFile('w') as f: - f.write('rules:\n' - ' braces:\n' - ' max-spaces-inside: 1248\n') + f.write('rules:\n' ' braces:\n' ' max-spaces-inside: 1248\n') f.flush() - c = config.YamlLintConfig('extends: ' + f.name + '\n' - 'rules:\n' - ' braces:\n' - ' min-spaces-inside-empty: 2357\n') + c = config.YamlLintConfig( + 'extends: ' + f.name + '\n' + 'rules:\n' + ' braces:\n' + ' min-spaces-inside-empty: 2357\n' + ) self.assertEqual(c.rules['braces']['min-spaces-inside'], 0) self.assertEqual(c.rules['braces']['max-spaces-inside'], 1248) @@ -348,38 +408,32 @@ def test_extend_recursive_default_values(self): self.assertEqual(c.rules['braces']['max-spaces-inside-empty'], -1) with tempfile.NamedTemporaryFile('w') as f: - f.write('rules:\n' - ' colons:\n' - ' max-spaces-before: 1337\n') + f.write('rules:\n' ' colons:\n' ' max-spaces-before: 1337\n') f.flush() - c = config.YamlLintConfig('extends: ' + f.name + '\n' - 'rules:\n' - ' colons: enable\n') + c = config.YamlLintConfig( + 'extends: ' + f.name + '\n' 'rules:\n' ' colons: enable\n' + ) self.assertEqual(c.rules['colons']['max-spaces-before'], 1337) self.assertEqual(c.rules['colons']['max-spaces-after'], 1) - with tempfile.NamedTemporaryFile('w') as f1, \ - tempfile.NamedTemporaryFile('w') as f2: - f1.write('rules:\n' - ' colons:\n' - ' max-spaces-before: 1337\n') + with tempfile.NamedTemporaryFile('w') as f1, tempfile.NamedTemporaryFile( + 'w' + ) as f2: + f1.write('rules:\n' ' colons:\n' ' max-spaces-before: 1337\n') f1.flush() - f2.write('extends: ' + f1.name + '\n' - 'rules:\n' - ' colons: disable\n') + f2.write('extends: ' + f1.name + '\n' 'rules:\n' ' colons: disable\n') f2.flush() - c = config.YamlLintConfig('extends: ' + f2.name + '\n' - 'rules:\n' - ' colons: enable\n') + c = config.YamlLintConfig( + 'extends: ' + f2.name + '\n' 'rules:\n' ' colons: enable\n' + ) self.assertEqual(c.rules['colons']['max-spaces-before'], 0) self.assertEqual(c.rules['colons']['max-spaces-after'], 1) def test_extended_ignore_str(self): with tempfile.NamedTemporaryFile('w') as f: - f.write('ignore: |\n' - ' *.template.yaml\n') + f.write('ignore: |\n' ' *.template.yaml\n') f.flush() c = config.YamlLintConfig('extends: ' + f.name + '\n') @@ -388,8 +442,7 @@ def test_extended_ignore_str(self): def test_extended_ignore_list(self): with tempfile.NamedTemporaryFile('w') as f: - f.write('ignore:\n' - ' - "*.template.yaml"\n') + f.write('ignore:\n' ' - "*.template.yaml"\n') f.flush() c = config.YamlLintConfig('extends: ' + f.name + '\n') @@ -400,9 +453,9 @@ def test_extended_ignore_list(self): class ExtendedLibraryConfigTestCase(unittest.TestCase): def test_extend_config_disable_rule(self): old = config.YamlLintConfig('extends: default') - new = config.YamlLintConfig('extends: default\n' - 'rules:\n' - ' trailing-spaces: disable\n') + new = config.YamlLintConfig( + 'extends: default\n' 'rules:\n' ' trailing-spaces: disable\n' + ) old.rules['trailing-spaces'] = False @@ -412,12 +465,14 @@ def test_extend_config_disable_rule(self): def test_extend_config_override_whole_rule(self): old = config.YamlLintConfig('extends: default') - new = config.YamlLintConfig('extends: default\n' - 'rules:\n' - ' empty-lines:\n' - ' max: 42\n' - ' max-start: 43\n' - ' max-end: 44\n') + new = config.YamlLintConfig( + 'extends: default\n' + 'rules:\n' + ' empty-lines:\n' + ' max: 42\n' + ' max-start: 43\n' + ' max-end: 44\n' + ) old.rules['empty-lines']['max'] = 42 old.rules['empty-lines']['max-start'] = 43 @@ -432,10 +487,9 @@ def test_extend_config_override_whole_rule(self): def test_extend_config_override_rule_partly(self): old = config.YamlLintConfig('extends: default') - new = config.YamlLintConfig('extends: default\n' - 'rules:\n' - ' empty-lines:\n' - ' max-start: 42\n') + new = config.YamlLintConfig( + 'extends: default\n' 'rules:\n' ' empty-lines:\n' ' max-start: 42\n' + ) old.rules['empty-lines']['max-start'] = 42 @@ -452,25 +506,29 @@ class IgnoreConfigTestCase(unittest.TestCase): def setUpClass(cls): super().setUpClass() - bad_yaml = ('---\n' - '- key: val1\n' - ' key: val2\n' - '- trailing space \n' - '- lonely hyphen\n') - - cls.wd = build_temp_workspace({ - 'bin/file.lint-me-anyway.yaml': bad_yaml, - 'bin/file.yaml': bad_yaml, - 'file-at-root.yaml': bad_yaml, - 'file.dont-lint-me.yaml': bad_yaml, - 'ign-dup/file.yaml': bad_yaml, - 'ign-dup/sub/dir/file.yaml': bad_yaml, - 'ign-trail/file.yaml': bad_yaml, - 'include/ign-dup/sub/dir/file.yaml': bad_yaml, - 's/s/ign-trail/file.yaml': bad_yaml, - 's/s/ign-trail/s/s/file.yaml': bad_yaml, - 's/s/ign-trail/s/s/file2.lint-me-anyway.yaml': bad_yaml, - }) + bad_yaml = ( + '---\n' + '- key: val1\n' + ' key: val2\n' + '- trailing space \n' + '- lonely hyphen\n' + ) + + cls.wd = build_temp_workspace( + { + 'bin/file.lint-me-anyway.yaml': bad_yaml, + 'bin/file.yaml': bad_yaml, + 'file-at-root.yaml': bad_yaml, + 'file.dont-lint-me.yaml': bad_yaml, + 'ign-dup/file.yaml': bad_yaml, + 'ign-dup/sub/dir/file.yaml': bad_yaml, + 'ign-trail/file.yaml': bad_yaml, + 'include/ign-dup/sub/dir/file.yaml': bad_yaml, + 's/s/ign-trail/file.yaml': bad_yaml, + 's/s/ign-trail/s/s/file.yaml': bad_yaml, + 's/s/ign-trail/s/s/file2.lint-me-anyway.yaml': bad_yaml, + } + ) cls.backup_wd = os.getcwd() os.chdir(cls.wd) @@ -486,27 +544,32 @@ def tearDownClass(cls): def test_mutually_exclusive_ignore_keys(self): self.assertRaises( YamlLintConfigError, - config.YamlLintConfig, 'extends: default\n' - 'ignore-from-file: .gitignore\n' - 'ignore: |\n' - ' *.dont-lint-me.yaml\n' - ' /bin/\n') + config.YamlLintConfig, + 'extends: default\n' + 'ignore-from-file: .gitignore\n' + 'ignore: |\n' + ' *.dont-lint-me.yaml\n' + ' /bin/\n', + ) def test_ignore_from_file_not_exist(self): self.assertRaises( FileNotFoundError, - config.YamlLintConfig, 'extends: default\n' - 'ignore-from-file: not_found_file\n') + config.YamlLintConfig, + 'extends: default\n' 'ignore-from-file: not_found_file\n', + ) def test_ignore_from_file_incorrect_type(self): self.assertRaises( YamlLintConfigError, - config.YamlLintConfig, 'extends: default\n' - 'ignore-from-file: 0\n') + config.YamlLintConfig, + 'extends: default\n' 'ignore-from-file: 0\n', + ) self.assertRaises( YamlLintConfigError, - config.YamlLintConfig, 'extends: default\n' - 'ignore-from-file: [0]\n') + config.YamlLintConfig, + 'extends: default\n' 'ignore-from-file: [0]\n', + ) def test_no_ignore(self): sys.stdout = StringIO() @@ -520,57 +583,64 @@ def test_no_ignore(self): trailing = '[error] trailing spaces (trailing-spaces)' hyphen = '[error] too many spaces after hyphen (hyphens)' - self.assertEqual(out, '\n'.join(( - './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, - './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, - './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, - './bin/file.yaml:3:3: ' + keydup, - './bin/file.yaml:4:17: ' + trailing, - './bin/file.yaml:5:5: ' + hyphen, - './file-at-root.yaml:3:3: ' + keydup, - './file-at-root.yaml:4:17: ' + trailing, - './file-at-root.yaml:5:5: ' + hyphen, - './file.dont-lint-me.yaml:3:3: ' + keydup, - './file.dont-lint-me.yaml:4:17: ' + trailing, - './file.dont-lint-me.yaml:5:5: ' + hyphen, - './ign-dup/file.yaml:3:3: ' + keydup, - './ign-dup/file.yaml:4:17: ' + trailing, - './ign-dup/file.yaml:5:5: ' + hyphen, - './ign-dup/sub/dir/file.yaml:3:3: ' + keydup, - './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './ign-trail/file.yaml:3:3: ' + keydup, - './ign-trail/file.yaml:4:17: ' + trailing, - './ign-trail/file.yaml:5:5: ' + hyphen, - './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, - './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/file.yaml:4:17: ' + trailing, - './s/s/ign-trail/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, - './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, - ))) + self.assertEqual( + out, + '\n'.join( + ( + './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, + './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, + './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, + './bin/file.yaml:3:3: ' + keydup, + './bin/file.yaml:4:17: ' + trailing, + './bin/file.yaml:5:5: ' + hyphen, + './file-at-root.yaml:3:3: ' + keydup, + './file-at-root.yaml:4:17: ' + trailing, + './file-at-root.yaml:5:5: ' + hyphen, + './file.dont-lint-me.yaml:3:3: ' + keydup, + './file.dont-lint-me.yaml:4:17: ' + trailing, + './file.dont-lint-me.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:3:3: ' + keydup, + './ign-dup/file.yaml:4:17: ' + trailing, + './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:4:17: ' + trailing, + './ign-trail/file.yaml:5:5: ' + hyphen, + './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, + ) + ), + ) def test_run_with_ignore_str(self): with open(os.path.join(self.wd, '.yamllint'), 'w') as f: - f.write('extends: default\n' - 'ignore: |\n' - ' *.dont-lint-me.yaml\n' - ' /bin/\n' - ' !/bin/*.lint-me-anyway.yaml\n' - 'rules:\n' - ' key-duplicates:\n' - ' ignore: |\n' - ' /ign-dup\n' - ' trailing-spaces:\n' - ' ignore: |\n' - ' ign-trail\n' - ' !*.lint-me-anyway.yaml\n') + f.write( + 'extends: default\n' + 'ignore: |\n' + ' *.dont-lint-me.yaml\n' + ' /bin/\n' + ' !/bin/*.lint-me-anyway.yaml\n' + 'rules:\n' + ' key-duplicates:\n' + ' ignore: |\n' + ' /ign-dup\n' + ' trailing-spaces:\n' + ' ignore: |\n' + ' ign-trail\n' + ' !*.lint-me-anyway.yaml\n' + ) sys.stdout = StringIO() with self.assertRaises(SystemExit): @@ -584,47 +654,54 @@ def test_run_with_ignore_str(self): trailing = '[error] trailing spaces (trailing-spaces)' hyphen = '[error] too many spaces after hyphen (hyphens)' - self.assertEqual(out, '\n'.join(( - './.yamllint:1:1: ' + docstart, - './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, - './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, - './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, - './file-at-root.yaml:3:3: ' + keydup, - './file-at-root.yaml:4:17: ' + trailing, - './file-at-root.yaml:5:5: ' + hyphen, - './ign-dup/file.yaml:4:17: ' + trailing, - './ign-dup/file.yaml:5:5: ' + hyphen, - './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './ign-trail/file.yaml:3:3: ' + keydup, - './ign-trail/file.yaml:5:5: ' + hyphen, - './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, - './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, - ))) + self.assertEqual( + out, + '\n'.join( + ( + './.yamllint:1:1: ' + docstart, + './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, + './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, + './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, + './file-at-root.yaml:3:3: ' + keydup, + './file-at-root.yaml:4:17: ' + trailing, + './file-at-root.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:4:17: ' + trailing, + './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:5:5: ' + hyphen, + './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, + ) + ), + ) def test_run_with_ignore_list(self): with open(os.path.join(self.wd, '.yamllint'), 'w') as f: - f.write('extends: default\n' - 'ignore:\n' - ' - "*.dont-lint-me.yaml"\n' - ' - "/bin/"\n' - ' - "!/bin/*.lint-me-anyway.yaml"\n' - 'rules:\n' - ' key-duplicates:\n' - ' ignore:\n' - ' - "/ign-dup"\n' - ' trailing-spaces:\n' - ' ignore:\n' - ' - "ign-trail"\n' - ' - "!*.lint-me-anyway.yaml"\n') + f.write( + 'extends: default\n' + 'ignore:\n' + ' - "*.dont-lint-me.yaml"\n' + ' - "/bin/"\n' + ' - "!/bin/*.lint-me-anyway.yaml"\n' + 'rules:\n' + ' key-duplicates:\n' + ' ignore:\n' + ' - "/ign-dup"\n' + ' trailing-spaces:\n' + ' ignore:\n' + ' - "ign-trail"\n' + ' - "!*.lint-me-anyway.yaml"\n' + ) sys.stdout = StringIO() with self.assertRaises(SystemExit): @@ -638,44 +715,49 @@ def test_run_with_ignore_list(self): trailing = '[error] trailing spaces (trailing-spaces)' hyphen = '[error] too many spaces after hyphen (hyphens)' - self.assertEqual(out, '\n'.join(( - './.yamllint:1:1: ' + docstart, - './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, - './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, - './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, - './file-at-root.yaml:3:3: ' + keydup, - './file-at-root.yaml:4:17: ' + trailing, - './file-at-root.yaml:5:5: ' + hyphen, - './ign-dup/file.yaml:4:17: ' + trailing, - './ign-dup/file.yaml:5:5: ' + hyphen, - './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './ign-trail/file.yaml:3:3: ' + keydup, - './ign-trail/file.yaml:5:5: ' + hyphen, - './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, - './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, - ))) + self.assertEqual( + out, + '\n'.join( + ( + './.yamllint:1:1: ' + docstart, + './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, + './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, + './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, + './file-at-root.yaml:3:3: ' + keydup, + './file-at-root.yaml:4:17: ' + trailing, + './file-at-root.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:4:17: ' + trailing, + './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:5:5: ' + hyphen, + './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, + ) + ), + ) def test_run_with_ignore_from_file(self): with open(os.path.join(self.wd, '.yamllint'), 'w') as f: - f.write('extends: default\n' - 'ignore-from-file: .gitignore\n' - 'rules:\n' - ' key-duplicates:\n' - ' ignore-from-file: .ignore-key-duplicates\n') + f.write( + 'extends: default\n' + 'ignore-from-file: .gitignore\n' + 'rules:\n' + ' key-duplicates:\n' + ' ignore-from-file: .ignore-key-duplicates\n' + ) with open(os.path.join(self.wd, '.gitignore'), 'w') as f: - f.write('*.dont-lint-me.yaml\n' - '/bin/\n' - '!/bin/*.lint-me-anyway.yaml\n') + f.write('*.dont-lint-me.yaml\n' '/bin/\n' '!/bin/*.lint-me-anyway.yaml\n') with open(os.path.join(self.wd, '.ignore-key-duplicates'), 'w') as f: f.write('/ign-dup\n') @@ -692,42 +774,47 @@ def test_run_with_ignore_from_file(self): trailing = '[error] trailing spaces (trailing-spaces)' hyphen = '[error] too many spaces after hyphen (hyphens)' - self.assertEqual(out, '\n'.join(( - './.yamllint:1:1: ' + docstart, - './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, - './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, - './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, - './file-at-root.yaml:3:3: ' + keydup, - './file-at-root.yaml:4:17: ' + trailing, - './file-at-root.yaml:5:5: ' + hyphen, - './ign-dup/file.yaml:4:17: ' + trailing, - './ign-dup/file.yaml:5:5: ' + hyphen, - './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './ign-trail/file.yaml:3:3: ' + keydup, - './ign-trail/file.yaml:4:17: ' + trailing, - './ign-trail/file.yaml:5:5: ' + hyphen, - './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, - './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/file.yaml:4:17: ' + trailing, - './s/s/ign-trail/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, - './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, - ))) + self.assertEqual( + out, + '\n'.join( + ( + './.yamllint:1:1: ' + docstart, + './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, + './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, + './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, + './file-at-root.yaml:3:3: ' + keydup, + './file-at-root.yaml:4:17: ' + trailing, + './file-at-root.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:4:17: ' + trailing, + './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:4:17: ' + trailing, + './ign-trail/file.yaml:5:5: ' + hyphen, + './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, + ) + ), + ) def test_run_with_ignored_from_file(self): with open(os.path.join(self.wd, '.yamllint'), 'w') as f: - f.write('ignore-from-file: [.gitignore, .yamlignore]\n' - 'extends: default\n') + f.write( + 'ignore-from-file: [.gitignore, .yamlignore]\n' 'extends: default\n' + ) with open(os.path.join(self.wd, '.gitignore'), 'w') as f: - f.write('*.dont-lint-me.yaml\n' - '/bin/\n') + f.write('*.dont-lint-me.yaml\n' '/bin/\n') with open(os.path.join(self.wd, '.yamlignore'), 'w') as f: f.write('!/bin/*.lint-me-anyway.yaml\n') @@ -743,33 +830,38 @@ def test_run_with_ignored_from_file(self): trailing = '[error] trailing spaces (trailing-spaces)' hyphen = '[error] too many spaces after hyphen (hyphens)' - self.assertEqual(out, '\n'.join(( - './.yamllint:1:1: ' + docstart, - './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, - './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, - './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, - './file-at-root.yaml:3:3: ' + keydup, - './file-at-root.yaml:4:17: ' + trailing, - './file-at-root.yaml:5:5: ' + hyphen, - './ign-dup/file.yaml:3:3: ' + keydup, - './ign-dup/file.yaml:4:17: ' + trailing, - './ign-dup/file.yaml:5:5: ' + hyphen, - './ign-dup/sub/dir/file.yaml:3:3: ' + keydup, - './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './ign-trail/file.yaml:3:3: ' + keydup, - './ign-trail/file.yaml:4:17: ' + trailing, - './ign-trail/file.yaml:5:5: ' + hyphen, - './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, - './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, - './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/file.yaml:4:17: ' + trailing, - './s/s/ign-trail/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, - './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, - './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, - ))) + self.assertEqual( + out, + '\n'.join( + ( + './.yamllint:1:1: ' + docstart, + './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, + './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, + './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, + './file-at-root.yaml:3:3: ' + keydup, + './file-at-root.yaml:4:17: ' + trailing, + './file-at-root.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:3:3: ' + keydup, + './ign-dup/file.yaml:4:17: ' + trailing, + './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:4:17: ' + trailing, + './ign-trail/file.yaml:5:5: ' + hyphen, + './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, + ) + ), + ) diff --git a/tests/test_linter.py b/tests/test_linter.py index ea509d8a..3202e321 100644 --- a/tests/test_linter.py +++ b/tests/test_linter.py @@ -40,18 +40,17 @@ def test_run_on_int(self): self.assertRaises(TypeError, linter.run, 42, self.fake_config()) def test_run_on_list(self): - self.assertRaises(TypeError, linter.run, - ['h', 'e', 'l', 'l', 'o'], self.fake_config()) + self.assertRaises( + TypeError, linter.run, ['h', 'e', 'l', 'l', 'o'], self.fake_config() + ) def test_run_on_non_ascii_chars(self): - s = ('- hétérogénéité\n' - '# 19.99 €\n') + s = '- hétérogénéité\n' '# 19.99 €\n' linter.run(s, self.fake_config()) linter.run(s.encode('utf-8'), self.fake_config()) linter.run(s.encode('iso-8859-15'), self.fake_config()) - s = ('- お早う御座います。\n' - '# الأَبْجَدِيَّة العَرَبِيَّة\n') + s = '- お早う御座います。\n' '# الأَبْجَدِيَّة العَرَبِيَّة\n' linter.run(s, self.fake_config()) linter.run(s.encode('utf-8'), self.fake_config()) diff --git a/tests/test_module.py b/tests/test_module.py index 7f4f62ba..95108ffb 100644 --- a/tests/test_module.py +++ b/tests/test_module.py @@ -34,35 +34,36 @@ def setUp(self): # file in dir os.mkdir(os.path.join(self.wd, 'sub')) with open(os.path.join(self.wd, 'sub', 'nok.yaml'), 'w') as f: - f.write('---\n' - 'list: [ 1, 1, 2, 3, 5, 8] \n') + f.write('---\n' 'list: [ 1, 1, 2, 3, 5, 8] \n') def tearDown(self): shutil.rmtree(self.wd) def test_run_module_no_args(self): with self.assertRaises(subprocess.CalledProcessError) as ctx: - subprocess.check_output([PYTHON, '-m', 'yamllint'], - stderr=subprocess.STDOUT) + subprocess.check_output( + [PYTHON, '-m', 'yamllint'], stderr=subprocess.STDOUT + ) self.assertEqual(ctx.exception.returncode, 2) self.assertRegex(ctx.exception.output.decode(), r'^usage: yamllint') def test_run_module_on_bad_dir(self): with self.assertRaises(subprocess.CalledProcessError) as ctx: - subprocess.check_output([PYTHON, '-m', 'yamllint', - '/does/not/exist'], - stderr=subprocess.STDOUT) - self.assertRegex(ctx.exception.output.decode(), - r'No such file or directory') + subprocess.check_output( + [PYTHON, '-m', 'yamllint', '/does/not/exist'], stderr=subprocess.STDOUT + ) + self.assertRegex(ctx.exception.output.decode(), r'No such file or directory') def test_run_module_on_file(self): out = subprocess.check_output( - [PYTHON, '-m', 'yamllint', os.path.join(self.wd, 'warn.yaml')]) + [PYTHON, '-m', 'yamllint', os.path.join(self.wd, 'warn.yaml')] + ) lines = out.decode().splitlines() self.assertIn('/warn.yaml', lines[0]) - self.assertEqual('\n'.join(lines[1:]), - ' 1:1 warning missing document start "---"' - ' (document-start)\n') + self.assertEqual( + '\n'.join(lines[1:]), + ' 1:1 warning missing document start "---"' ' (document-start)\n', + ) def test_run_module_on_dir(self): with self.assertRaises(subprocess.CalledProcessError) as ctx: @@ -74,10 +75,12 @@ def test_run_module_on_dir(self): '/warn.yaml\n' ' 1:1 warning missing document start "---"' ' (document-start)', - files[0]) + files[0], + ) self.assertIn( '/sub/nok.yaml\n' ' 2:9 error too many spaces inside brackets' ' (brackets)\n' ' 2:27 error trailing spaces (trailing-spaces)', - files[1]) + files[1], + ) diff --git a/tests/test_parser.py b/tests/test_parser.py index c2b598ac..f9e103d7 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -47,11 +47,7 @@ def test_line_generator(self): e = list(line_generator('\n\n')) self.assertEqual(len(e), 3) - e = list(line_generator('---\n' - 'this is line 1\n' - 'line 2\n' - '\n' - '3\n')) + e = list(line_generator('---\n' 'this is line 1\n' 'line 2\n' '\n' '3\n')) self.assertEqual(len(e), 6) self.assertEqual(e[0].line_no, 1) self.assertEqual(e[0].content, '---') @@ -59,9 +55,7 @@ def test_line_generator(self): self.assertEqual(e[3].content, '') self.assertEqual(e[5].line_no, 6) - e = list(line_generator('test with\n' - 'no newline\n' - 'at the end')) + e = list(line_generator('test with\n' 'no newline\n' 'at the end')) self.assertEqual(len(e), 3) self.assertEqual(e[2].line_no, 3) self.assertEqual(e[2].content, 'at the end') @@ -76,20 +70,23 @@ def test_token_or_comment_generator(self): self.assertEqual(e[1].curr, e[0].next) self.assertIsNone(e[1].next) - e = list(token_or_comment_generator('---\n' - 'k: v\n')) + e = list(token_or_comment_generator('---\n' 'k: v\n')) self.assertEqual(len(e), 9) self.assertIsInstance(e[3].curr, yaml.KeyToken) self.assertIsInstance(e[5].curr, yaml.ValueToken) - e = list(token_or_comment_generator('# start comment\n' - '- a\n' - '- key: val # key=val\n' - '# this is\n' - '# a block \n' - '# comment\n' - '- c\n' - '# end comment\n')) + e = list( + token_or_comment_generator( + '# start comment\n' + '- a\n' + '- key: val # key=val\n' + '# this is\n' + '# a block \n' + '# comment\n' + '- c\n' + '# end comment\n' + ) + ) self.assertEqual(len(e), 21) self.assertIsInstance(e[1], Comment) self.assertEqual(e[1], Comment(1, 1, '# start comment', 0)) @@ -99,35 +96,36 @@ def test_token_or_comment_generator(self): self.assertEqual(e[14], Comment(6, 1, '# comment', 0)) self.assertEqual(e[18], Comment(8, 1, '# end comment', 0)) - e = list(token_or_comment_generator('---\n' - '# no newline char')) + e = list(token_or_comment_generator('---\n' '# no newline char')) self.assertEqual(e[2], Comment(2, 1, '# no newline char', 0)) e = list(token_or_comment_generator('# just comment')) self.assertEqual(e[1], Comment(1, 1, '# just comment', 0)) - e = list(token_or_comment_generator('\n' - ' # indented comment\n')) + e = list(token_or_comment_generator('\n' ' # indented comment\n')) self.assertEqual(e[1], Comment(2, 4, '# indented comment', 0)) - e = list(token_or_comment_generator('\n' - '# trailing spaces \n')) + e = list(token_or_comment_generator('\n' '# trailing spaces \n')) self.assertEqual(e[1], Comment(2, 1, '# trailing spaces ', 0)) - e = [c for c in - token_or_comment_generator('# block\n' - '# comment\n' - '- data # inline comment\n' - '# block\n' - '# comment\n' - '- k: v # inline comment\n' - '- [ l, ist\n' - '] # inline comment\n' - '- { m: ap\n' - '} # inline comment\n' - '# block comment\n' - '- data # inline comment\n') - if isinstance(c, Comment)] + e = [ + c + for c in token_or_comment_generator( + '# block\n' + '# comment\n' + '- data # inline comment\n' + '# block\n' + '# comment\n' + '- k: v # inline comment\n' + '- [ l, ist\n' + '] # inline comment\n' + '- { m: ap\n' + '} # inline comment\n' + '# block comment\n' + '- data # inline comment\n' + ) + if isinstance(c, Comment) + ] self.assertEqual(len(e), 10) self.assertFalse(e[0].is_inline()) self.assertFalse(e[1].is_inline()) @@ -141,8 +139,7 @@ def test_token_or_comment_generator(self): self.assertTrue(e[9].is_inline()) def test_token_or_comment_or_line_generator(self): - e = list(token_or_comment_or_line_generator('---\n' - 'k: v # k=v\n')) + e = list(token_or_comment_or_line_generator('---\n' 'k: v # k=v\n')) self.assertEqual(len(e), 13) self.assertIsInstance(e[0], Token) self.assertIsInstance(e[0].curr, yaml.StreamStartToken) diff --git a/tests/test_spec_examples.py b/tests/test_spec_examples.py index eb1582ef..0c23ec06 100644 --- a/tests/test_spec_examples.py +++ b/tests/test_spec_examples.py @@ -42,69 +42,76 @@ # encoding='utf-8') as g: # g.write(text) + class SpecificationTestCase(RuleTestCase): rule_id = None -conf_general = ('document-start: disable\n' - 'comments: {min-spaces-from-content: 1}\n' - 'braces: {min-spaces-inside: 1, max-spaces-inside: 1}\n' - 'brackets: {min-spaces-inside: 1, max-spaces-inside: 1}\n') +conf_general = ( + 'document-start: disable\n' + 'comments: {min-spaces-from-content: 1}\n' + 'braces: {min-spaces-inside: 1, max-spaces-inside: 1}\n' + 'brackets: {min-spaces-inside: 1, max-spaces-inside: 1}\n' +) conf_overrides = { 'example-2.2': 'colons: {max-spaces-after: 2}\n', 'example-2.4': 'colons: {max-spaces-after: 3}\n', - 'example-2.5': ('empty-lines: {max-end: 2}\n' - 'brackets: {min-spaces-inside: 0, max-spaces-inside: 2}\n' - 'commas: {max-spaces-before: -1}\n'), - 'example-2.6': ('braces: {min-spaces-inside: 0, max-spaces-inside: 0}\n' - 'indentation: disable\n'), - 'example-2.12': ('empty-lines: {max-end: 1}\n' - 'colons: {max-spaces-before: -1}\n'), + 'example-2.5': ( + 'empty-lines: {max-end: 2}\n' + 'brackets: {min-spaces-inside: 0, max-spaces-inside: 2}\n' + 'commas: {max-spaces-before: -1}\n' + ), + 'example-2.6': ( + 'braces: {min-spaces-inside: 0, max-spaces-inside: 0}\n' + 'indentation: disable\n' + ), + 'example-2.12': ('empty-lines: {max-end: 1}\n' 'colons: {max-spaces-before: -1}\n'), 'example-2.16': 'empty-lines: {max-end: 1}\n', 'example-2.18': 'empty-lines: {max-end: 1}\n', 'example-2.19': 'empty-lines: {max-end: 1}\n', 'example-2.28': 'empty-lines: {max-end: 3}\n', - 'example-5.3': ('indentation: {indent-sequences: false}\n' - 'colons: {max-spaces-before: 1}\n'), + 'example-5.3': ( + 'indentation: {indent-sequences: false}\n' 'colons: {max-spaces-before: 1}\n' + ), 'example-6.4': 'trailing-spaces: disable\n', 'example-6.5': 'trailing-spaces: disable\n', 'example-6.6': 'trailing-spaces: disable\n', 'example-6.7': 'trailing-spaces: disable\n', 'example-6.8': 'trailing-spaces: disable\n', - 'example-6.10': ('empty-lines: {max-end: 2}\n' - 'trailing-spaces: disable\n' - 'comments-indentation: disable\n'), - 'example-6.11': ('empty-lines: {max-end: 1}\n' - 'comments-indentation: disable\n'), + 'example-6.10': ( + 'empty-lines: {max-end: 2}\n' + 'trailing-spaces: disable\n' + 'comments-indentation: disable\n' + ), + 'example-6.11': ('empty-lines: {max-end: 1}\n' 'comments-indentation: disable\n'), 'example-6.13': 'comments-indentation: disable\n', 'example-6.14': 'comments-indentation: disable\n', 'example-6.23': 'colons: {max-spaces-before: 1}\n', - 'example-7.4': ('colons: {max-spaces-before: 1}\n' - 'indentation: disable\n'), + 'example-7.4': ('colons: {max-spaces-before: 1}\n' 'indentation: disable\n'), 'example-7.5': 'trailing-spaces: disable\n', 'example-7.6': 'trailing-spaces: disable\n', 'example-7.7': 'indentation: disable\n', - 'example-7.8': ('colons: {max-spaces-before: 1}\n' - 'indentation: disable\n'), + 'example-7.8': ('colons: {max-spaces-before: 1}\n' 'indentation: disable\n'), 'example-7.9': 'trailing-spaces: disable\n', - 'example-7.11': ('colons: {max-spaces-before: 1}\n' - 'indentation: disable\n'), - 'example-7.13': ('brackets: {min-spaces-inside: 0, max-spaces-inside: 1}\n' - 'commas: {max-spaces-before: 1, min-spaces-after: 0}\n'), + 'example-7.11': ('colons: {max-spaces-before: 1}\n' 'indentation: disable\n'), + 'example-7.13': ( + 'brackets: {min-spaces-inside: 0, max-spaces-inside: 1}\n' + 'commas: {max-spaces-before: 1, min-spaces-after: 0}\n' + ), 'example-7.14': 'indentation: disable\n', - 'example-7.15': ('braces: {min-spaces-inside: 0, max-spaces-inside: 1}\n' - 'commas: {max-spaces-before: 1, min-spaces-after: 0}\n' - 'colons: {max-spaces-before: 1}\n'), + 'example-7.15': ( + 'braces: {min-spaces-inside: 0, max-spaces-inside: 1}\n' + 'commas: {max-spaces-before: 1, min-spaces-after: 0}\n' + 'colons: {max-spaces-before: 1}\n' + ), 'example-7.16': 'indentation: disable\n', 'example-7.17': 'indentation: disable\n', 'example-7.18': 'indentation: disable\n', 'example-7.19': 'indentation: disable\n', - 'example-7.20': ('colons: {max-spaces-before: 1}\n' - 'indentation: disable\n'), + 'example-7.20': ('colons: {max-spaces-before: 1}\n' 'indentation: disable\n'), 'example-8.1': 'empty-lines: {max-end: 1}\n', 'example-8.2': 'trailing-spaces: disable\n', - 'example-8.5': ('comments-indentation: disable\n' - 'trailing-spaces: disable\n'), + 'example-8.5': ('comments-indentation: disable\n' 'trailing-spaces: disable\n'), 'example-8.6': 'empty-lines: {max-end: 1}\n', 'example-8.7': 'empty-lines: {max-end: 1}\n', 'example-8.8': 'trailing-spaces: disable\n', @@ -112,8 +119,9 @@ class SpecificationTestCase(RuleTestCase): 'example-8.14': 'colons: {max-spaces-before: 1}\n', 'example-8.16': 'indentation: {spaces: 1}\n', 'example-8.17': 'indentation: disable\n', - 'example-8.20': ('indentation: {indent-sequences: false}\n' - 'colons: {max-spaces-before: 1}\n'), + 'example-8.20': ( + 'indentation: {indent-sequences: false}\n' 'colons: {max-spaces-before: 1}\n' + ), 'example-8.22': 'indentation: disable\n', 'example-10.1': 'colons: {max-spaces-before: 2}\n', 'example-10.2': 'indentation: {indent-sequences: false}\n', @@ -121,14 +129,16 @@ class SpecificationTestCase(RuleTestCase): 'example-10.9': 'truthy: disable\n', } -files = os.listdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), - 'yaml-1.2-spec-examples')) +files = os.listdir( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'yaml-1.2-spec-examples') +) assert len(files) == 132 def _gen_test(buffer, conf): def test(self): self.check(buffer, conf) + return test @@ -183,5 +193,4 @@ def test(self): with open('tests/yaml-1.2-spec-examples/' + file, encoding='utf-8') as f: conf = conf_general + conf_overrides.get(file, '') - setattr(SpecificationTestCase, 'test_' + file, - _gen_test(f.read(), conf)) + setattr(SpecificationTestCase, 'test_' + file, _gen_test(f.read(), conf)) diff --git a/tests/test_syntax_errors.py b/tests/test_syntax_errors.py index 507ab5a9..51c44926 100644 --- a/tests/test_syntax_errors.py +++ b/tests/test_syntax_errors.py @@ -20,74 +20,62 @@ class YamlLintTestCase(RuleTestCase): rule_id = None # syntax error def test_syntax_errors(self): - self.check('---\n' - 'this is not: valid: YAML\n', None, problem=(2, 19)) - self.check('---\n' - 'this is: valid YAML\n' - '\n' - 'this is an error: [\n' - '\n' - '...\n', None, problem=(6, 1)) - self.check('%YAML 1.2\n' - '%TAG ! tag:clarkevans.com,2002:\n' - 'doc: ument\n' - '...\n', None, problem=(3, 1)) + self.check('---\n' 'this is not: valid: YAML\n', None, problem=(2, 19)) + self.check( + '---\n' 'this is: valid YAML\n' '\n' 'this is an error: [\n' '\n' '...\n', + None, + problem=(6, 1), + ) + self.check( + '%YAML 1.2\n' '%TAG ! tag:clarkevans.com,2002:\n' 'doc: ument\n' '...\n', + None, + problem=(3, 1), + ) def test_empty_flows(self): - self.check('---\n' - '- []\n' - '- {}\n' - '- [\n' - ']\n' - '- {\n' - '}\n' - '...\n', None) + self.check('---\n' '- []\n' '- {}\n' '- [\n' ']\n' '- {\n' '}\n' '...\n', None) def test_explicit_mapping(self): - self.check('---\n' - '? key\n' - ': - value 1\n' - ' - value 2\n' - '...\n', None) - self.check('---\n' - '?\n' - ' key\n' - ': {a: 1}\n' - '...\n', None) - self.check('---\n' - '?\n' - ' key\n' - ':\n' - ' val\n' - '...\n', None) + self.check('---\n' '? key\n' ': - value 1\n' ' - value 2\n' '...\n', None) + self.check('---\n' '?\n' ' key\n' ': {a: 1}\n' '...\n', None) + self.check('---\n' '?\n' ' key\n' ':\n' ' val\n' '...\n', None) def test_mapping_between_sequences(self): # This is valid YAML. See http://www.yaml.org/spec/1.2/spec.html, # example 2.11 - self.check('---\n' - '? - Detroit Tigers\n' - ' - Chicago cubs\n' - ':\n' - ' - 2001-07-23\n' - '\n' - '? [New York Yankees,\n' - ' Atlanta Braves]\n' - ': [2001-07-02, 2001-08-12,\n' - ' 2001-08-14]\n', None) + self.check( + '---\n' + '? - Detroit Tigers\n' + ' - Chicago cubs\n' + ':\n' + ' - 2001-07-23\n' + '\n' + '? [New York Yankees,\n' + ' Atlanta Braves]\n' + ': [2001-07-02, 2001-08-12,\n' + ' 2001-08-14]\n', + None, + ) def test_sets(self): - self.check('---\n' - '? key one\n' - '? key two\n' - '? [non, scalar, key]\n' - '? key with value\n' - ': value\n' - '...\n', None) - self.check('---\n' - '? - multi\n' - ' - line\n' - ' - keys\n' - '? in:\n' - ' a:\n' - ' set\n' - '...\n', None) + self.check( + '---\n' + '? key one\n' + '? key two\n' + '? [non, scalar, key]\n' + '? key with value\n' + ': value\n' + '...\n', + None, + ) + self.check( + '---\n' + '? - multi\n' + ' - line\n' + ' - keys\n' + '? in:\n' + ' a:\n' + ' set\n' + '...\n', + None, + ) diff --git a/tests/test_yamllint_directives.py b/tests/test_yamllint_directives.py index c138144f..5097edee 100644 --- a/tests/test_yamllint_directives.py +++ b/tests/test_yamllint_directives.py @@ -17,416 +17,477 @@ class YamllintDirectivesTestCase(RuleTestCase): - conf = ('commas: disable\n' - 'trailing-spaces: {}\n' - 'colons: {max-spaces-before: 1}\n') + conf = ( + 'commas: disable\n' 'trailing-spaces: {}\n' 'colons: {max-spaces-before: 1}\n' + ) def test_disable_directive(self): - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(4, 8, 'colons'), - problem3=(6, 7, 'colons'), - problem4=(6, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '# yamllint disable\n' - '- bad : colon\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem=(3, 18, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '# yamllint disable\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '# yamllint enable\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(8, 7, 'colons'), - problem2=(8, 26, 'trailing-spaces')) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(4, 8, 'colons'), + problem3=(6, 7, 'colons'), + problem4=(6, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '# yamllint disable\n' + '- bad : colon\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem=(3, 18, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '# yamllint disable\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '# yamllint enable\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(8, 7, 'colons'), + problem2=(8, 26, 'trailing-spaces'), + ) def test_disable_directive_with_rules(self): - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '# yamllint disable rule:trailing-spaces\n' - '- bad : colon\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(5, 8, 'colons'), - problem3=(7, 7, 'colons')) - self.check('---\n' - '- [valid , YAML]\n' - '# yamllint disable rule:trailing-spaces\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '# yamllint enable rule:trailing-spaces\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(5, 8, 'colons'), - problem2=(8, 7, 'colons'), - problem3=(8, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '# yamllint disable rule:trailing-spaces\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '# yamllint enable\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(5, 8, 'colons'), - problem2=(8, 7, 'colons'), - problem3=(8, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '# yamllint disable\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '# yamllint enable rule:trailing-spaces\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem=(8, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '# yamllint disable rule:colons\n' - '- trailing spaces \n' - '# yamllint disable rule:trailing-spaces\n' - '- bad : colon\n' - '- [valid , YAML]\n' - '# yamllint enable rule:colons\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(4, 18, 'trailing-spaces'), - problem2=(9, 7, 'colons')) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '# yamllint disable rule:trailing-spaces\n' + '- bad : colon\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(5, 8, 'colons'), + problem3=(7, 7, 'colons'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '# yamllint disable rule:trailing-spaces\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '# yamllint enable rule:trailing-spaces\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(5, 8, 'colons'), + problem2=(8, 7, 'colons'), + problem3=(8, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '# yamllint disable rule:trailing-spaces\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '# yamllint enable\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(5, 8, 'colons'), + problem2=(8, 7, 'colons'), + problem3=(8, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '# yamllint disable\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '# yamllint enable rule:trailing-spaces\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem=(8, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '# yamllint disable rule:colons\n' + '- trailing spaces \n' + '# yamllint disable rule:trailing-spaces\n' + '- bad : colon\n' + '- [valid , YAML]\n' + '# yamllint enable rule:colons\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(4, 18, 'trailing-spaces'), + problem2=(9, 7, 'colons'), + ) def test_disable_line_directive(self): - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '# yamllint disable-line\n' - '- bad : colon\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(7, 7, 'colons'), - problem3=(7, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '- bad : colon # yamllint disable-line\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(6, 7, 'colons'), - problem3=(6, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML] # yamllint disable-line\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(4, 8, 'colons'), - problem3=(6, 7, 'colons'), - problem4=(6, 26, 'trailing-spaces')) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '# yamllint disable-line\n' + '- bad : colon\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(7, 7, 'colons'), + problem3=(7, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '- bad : colon # yamllint disable-line\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(6, 7, 'colons'), + problem3=(6, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML] # yamllint disable-line\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(4, 8, 'colons'), + problem3=(6, 7, 'colons'), + problem4=(6, 26, 'trailing-spaces'), + ) def test_disable_line_directive_with_rules(self): - self.check('---\n' - '- [valid , YAML]\n' - '# yamllint disable-line rule:colons\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(4, 18, 'trailing-spaces'), - problem2=(5, 8, 'colons'), - problem3=(7, 7, 'colons'), - problem4=(7, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces # yamllint disable-line rule:colons \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 55, 'trailing-spaces'), - problem2=(4, 8, 'colons'), - problem3=(6, 7, 'colons'), - problem4=(6, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '# yamllint disable-line rule:colons\n' - '- bad : colon\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(7, 7, 'colons'), - problem3=(7, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '- bad : colon # yamllint disable-line rule:colons\n' - '- [valid , YAML]\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(6, 7, 'colons'), - problem3=(6, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '# yamllint disable-line rule:colons\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(4, 8, 'colons'), - problem3=(7, 26, 'trailing-spaces')) - self.check('---\n' - '- [valid , YAML]\n' - '- trailing spaces \n' - '- bad : colon\n' - '- [valid , YAML]\n' - '# yamllint disable-line rule:colons rule:trailing-spaces\n' - '- bad : colon and spaces \n' - '- [valid , YAML]\n', - self.conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(4, 8, 'colons')) + self.check( + '---\n' + '- [valid , YAML]\n' + '# yamllint disable-line rule:colons\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(4, 18, 'trailing-spaces'), + problem2=(5, 8, 'colons'), + problem3=(7, 7, 'colons'), + problem4=(7, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces # yamllint disable-line rule:colons \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 55, 'trailing-spaces'), + problem2=(4, 8, 'colons'), + problem3=(6, 7, 'colons'), + problem4=(6, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '# yamllint disable-line rule:colons\n' + '- bad : colon\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(7, 7, 'colons'), + problem3=(7, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '- bad : colon # yamllint disable-line rule:colons\n' + '- [valid , YAML]\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(6, 7, 'colons'), + problem3=(6, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '# yamllint disable-line rule:colons\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(4, 8, 'colons'), + problem3=(7, 26, 'trailing-spaces'), + ) + self.check( + '---\n' + '- [valid , YAML]\n' + '- trailing spaces \n' + '- bad : colon\n' + '- [valid , YAML]\n' + '# yamllint disable-line rule:colons rule:trailing-spaces\n' + '- bad : colon and spaces \n' + '- [valid , YAML]\n', + self.conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(4, 8, 'colons'), + ) def test_disable_directive_with_rules_and_dos_lines(self): conf = self.conf + 'new-lines: {type: dos}\n' - self.check('---\r\n' - '- [valid , YAML]\r\n' - '# yamllint disable rule:trailing-spaces\r\n' - '- trailing spaces \r\n' - '- bad : colon\r\n' - '- [valid , YAML]\r\n' - '# yamllint enable rule:trailing-spaces\r\n' - '- bad : colon and spaces \r\n' - '- [valid , YAML]\r\n', - conf, - problem1=(5, 8, 'colons'), - problem2=(8, 7, 'colons'), - problem3=(8, 26, 'trailing-spaces')) - self.check('---\r\n' - '- [valid , YAML]\r\n' - '- trailing spaces \r\n' - '- bad : colon\r\n' - '- [valid , YAML]\r\n' - '# yamllint disable-line rule:colons\r\n' - '- bad : colon and spaces \r\n' - '- [valid , YAML]\r\n', - conf, - problem1=(3, 18, 'trailing-spaces'), - problem2=(4, 8, 'colons'), - problem3=(7, 26, 'trailing-spaces')) + self.check( + '---\r\n' + '- [valid , YAML]\r\n' + '# yamllint disable rule:trailing-spaces\r\n' + '- trailing spaces \r\n' + '- bad : colon\r\n' + '- [valid , YAML]\r\n' + '# yamllint enable rule:trailing-spaces\r\n' + '- bad : colon and spaces \r\n' + '- [valid , YAML]\r\n', + conf, + problem1=(5, 8, 'colons'), + problem2=(8, 7, 'colons'), + problem3=(8, 26, 'trailing-spaces'), + ) + self.check( + '---\r\n' + '- [valid , YAML]\r\n' + '- trailing spaces \r\n' + '- bad : colon\r\n' + '- [valid , YAML]\r\n' + '# yamllint disable-line rule:colons\r\n' + '- bad : colon and spaces \r\n' + '- [valid , YAML]\r\n', + conf, + problem1=(3, 18, 'trailing-spaces'), + problem2=(4, 8, 'colons'), + problem3=(7, 26, 'trailing-spaces'), + ) def test_directive_on_last_line(self): conf = 'new-line-at-end-of-file: {}' - self.check('---\n' - 'no new line', - conf, - problem=(2, 12, 'new-line-at-end-of-file')) - self.check('---\n' - '# yamllint disable\n' - 'no new line', - conf) - self.check('---\n' - 'no new line # yamllint disable', - conf) + self.check( + '---\n' 'no new line', conf, problem=(2, 12, 'new-line-at-end-of-file') + ) + self.check('---\n' '# yamllint disable\n' 'no new line', conf) + self.check('---\n' 'no new line # yamllint disable', conf) def test_indented_directive(self): conf = 'brackets: {min-spaces-inside: 0, max-spaces-inside: 0}' - self.check('---\n' - '- a: 1\n' - ' b:\n' - ' c: [ x]\n', - conf, - problem=(4, 12, 'brackets')) - self.check('---\n' - '- a: 1\n' - ' b:\n' - ' # yamllint disable-line rule:brackets\n' - ' c: [ x]\n', - conf) + self.check( + '---\n' '- a: 1\n' ' b:\n' ' c: [ x]\n', + conf, + problem=(4, 12, 'brackets'), + ) + self.check( + '---\n' + '- a: 1\n' + ' b:\n' + ' # yamllint disable-line rule:brackets\n' + ' c: [ x]\n', + conf, + ) def test_directive_on_itself(self): - conf = ('comments: {min-spaces-from-content: 2}\n' - 'comments-indentation: {}\n') - self.check('---\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf, - problem1=(2, 8, 'comments'), - problem2=(4, 2, 'comments-indentation')) - self.check('---\n' - '# yamllint disable\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf) - self.check('---\n' - '- a: 1 # yamllint disable-line\n' - ' b:\n' - ' # yamllint disable-line\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf) - self.check('---\n' - '- a: 1 # yamllint disable-line rule:comments\n' - ' b:\n' - ' # yamllint disable-line rule:comments-indentation\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf) - self.check('---\n' - '# yamllint disable\n' - '- a: 1 # comment too close\n' - ' # yamllint enable rule:comments-indentation\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf, - problem=(6, 2, 'comments-indentation')) + conf = 'comments: {min-spaces-from-content: 2}\n' 'comments-indentation: {}\n' + self.check( + '---\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + problem1=(2, 8, 'comments'), + problem2=(4, 2, 'comments-indentation'), + ) + self.check( + '---\n' + '# yamllint disable\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + ) + self.check( + '---\n' + '- a: 1 # yamllint disable-line\n' + ' b:\n' + ' # yamllint disable-line\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + ) + self.check( + '---\n' + '- a: 1 # yamllint disable-line rule:comments\n' + ' b:\n' + ' # yamllint disable-line rule:comments-indentation\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + ) + self.check( + '---\n' + '# yamllint disable\n' + '- a: 1 # comment too close\n' + ' # yamllint enable rule:comments-indentation\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + problem=(6, 2, 'comments-indentation'), + ) def test_disable_file_directive(self): - conf = ('comments: {min-spaces-from-content: 2}\n' - 'comments-indentation: {}\n') - self.check('# yamllint disable-file\n' - '---\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf) - self.check('# yamllint disable-file\n' - '---\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf) - self.check('#yamllint disable-file\n' - '---\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf) - self.check('#yamllint disable-file \n' - '---\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf) - self.check('---\n' - '# yamllint disable-file\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf, - problem1=(3, 8, 'comments'), - problem2=(5, 2, 'comments-indentation')) - self.check('# yamllint disable-file: rules cannot be specified\n' - '---\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf, - problem1=(3, 8, 'comments'), - problem2=(5, 2, 'comments-indentation')) - self.check('AAAA yamllint disable-file\n' - '---\n' - '- a: 1 # comment too close\n' - ' b:\n' - ' # wrong indentation\n' - ' c: [x]\n', - conf, - problem1=(1, 1, 'document-start'), - problem2=(3, 8, 'comments'), - problem3=(5, 2, 'comments-indentation')) + conf = 'comments: {min-spaces-from-content: 2}\n' 'comments-indentation: {}\n' + self.check( + '# yamllint disable-file\n' + '---\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + ) + self.check( + '# yamllint disable-file\n' + '---\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + ) + self.check( + '#yamllint disable-file\n' + '---\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + ) + self.check( + '#yamllint disable-file \n' + '---\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + ) + self.check( + '---\n' + '# yamllint disable-file\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + problem1=(3, 8, 'comments'), + problem2=(5, 2, 'comments-indentation'), + ) + self.check( + '# yamllint disable-file: rules cannot be specified\n' + '---\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + problem1=(3, 8, 'comments'), + problem2=(5, 2, 'comments-indentation'), + ) + self.check( + 'AAAA yamllint disable-file\n' + '---\n' + '- a: 1 # comment too close\n' + ' b:\n' + ' # wrong indentation\n' + ' c: [x]\n', + conf, + problem1=(1, 1, 'document-start'), + problem2=(3, 8, 'comments'), + problem3=(5, 2, 'comments-indentation'), + ) def test_disable_file_directive_not_at_first_position(self): - self.check('# yamllint disable-file\n' - '---\n' - '- bad : colon and spaces \n', - self.conf) - self.check('---\n' - '# yamllint disable-file\n' - '- bad : colon and spaces \n', - self.conf, - problem1=(3, 7, 'colons'), - problem2=(3, 26, 'trailing-spaces')) + self.check( + '# yamllint disable-file\n' '---\n' '- bad : colon and spaces \n', + self.conf, + ) + self.check( + '---\n' '# yamllint disable-file\n' '- bad : colon and spaces \n', + self.conf, + problem1=(3, 7, 'colons'), + problem2=(3, 26, 'trailing-spaces'), + ) def test_disable_file_directive_with_syntax_error(self): - self.check('# This file is not valid YAML (it is a Jinja template)\n' - '{% if extra_info %}\n' - 'key1: value1\n' - '{% endif %}\n' - 'key2: value2\n', - self.conf, - problem=(2, 2, 'syntax')) - self.check('# yamllint disable-file\n' - '# This file is not valid YAML (it is a Jinja template)\n' - '{% if extra_info %}\n' - 'key1: value1\n' - '{% endif %}\n' - 'key2: value2\n', - self.conf) + self.check( + '# This file is not valid YAML (it is a Jinja template)\n' + '{% if extra_info %}\n' + 'key1: value1\n' + '{% endif %}\n' + 'key2: value2\n', + self.conf, + problem=(2, 2, 'syntax'), + ) + self.check( + '# yamllint disable-file\n' + '# This file is not valid YAML (it is a Jinja template)\n' + '{% if extra_info %}\n' + 'key1: value1\n' + '{% endif %}\n' + 'key2: value2\n', + self.conf, + ) def test_disable_file_directive_with_dos_lines(self): - self.check('# yamllint disable-file\r\n' - '---\r\n' - '- bad : colon and spaces \r\n', - self.conf) - self.check('# yamllint disable-file\r\n' - '# This file is not valid YAML (it is a Jinja template)\r\n' - '{% if extra_info %}\r\n' - 'key1: value1\r\n' - '{% endif %}\r\n' - 'key2: value2\r\n', - self.conf) + self.check( + '# yamllint disable-file\r\n' '---\r\n' '- bad : colon and spaces \r\n', + self.conf, + ) + self.check( + '# yamllint disable-file\r\n' + '# This file is not valid YAML (it is a Jinja template)\r\n' + '{% if extra_info %}\r\n' + 'key1: value1\r\n' + '{% endif %}\r\n' + 'key2: value2\r\n', + self.conf, + ) diff --git a/yamllint/cli.py b/yamllint/cli.py index 8d13000a..7a8a4dd0 100644 --- a/yamllint/cli.py +++ b/yamllint/cli.py @@ -37,19 +37,23 @@ def find_files_recursively(items, conf): def supports_color(): - supported_platform = not (platform.system() == 'Windows' and not - ('ANSICON' in os.environ or - ('TERM' in os.environ and - os.environ['TERM'] == 'ANSI'))) - return (supported_platform and - hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()) + supported_platform = not ( + platform.system() == 'Windows' + and not ( + 'ANSICON' in os.environ + or ('TERM' in os.environ and os.environ['TERM'] == 'ANSI') + ) + ) + return supported_platform and hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() class Format: @staticmethod def parsable(problem, filename): - return (f'{filename}:{problem.line}:{problem.column}: ' - f'[{problem.level}] {problem.message}') + return ( + f'{filename}:{problem.line}:{problem.column}: ' + f'[{problem.level}] {problem.message}' + ) @staticmethod def standard(problem, filename): @@ -78,9 +82,11 @@ def standard_color(problem, filename): @staticmethod def github(problem, filename): - line = f'::{problem.level} file={filename},' \ - f'line={problem.line},col={problem.column}' \ - f'::{problem.line}:{problem.column} ' + line = ( + f'::{problem.level} file={filename},' + f'line={problem.line},col={problem.column}' + f'::{problem.line}:{problem.column} ' + ) if problem.rule: line += f'[{problem.rule}] ' line += problem.desc @@ -92,8 +98,7 @@ def show_problems(problems, file, args_format, no_warn): first = True if args_format == 'auto': - if ('GITHUB_ACTIONS' in os.environ and - 'GITHUB_WORKFLOW' in os.environ): + if 'GITHUB_ACTIONS' in os.environ and 'GITHUB_WORKFLOW' in os.environ: args_format = 'github' elif supports_color(): args_format = 'colored' @@ -143,46 +148,64 @@ def find_project_config_filepath(path='.'): def run(argv=None): - parser = argparse.ArgumentParser(prog=APP_NAME, - description=APP_DESCRIPTION) + parser = argparse.ArgumentParser(prog=APP_NAME, description=APP_DESCRIPTION) files_group = parser.add_mutually_exclusive_group(required=True) - files_group.add_argument('files', metavar='FILE_OR_DIR', nargs='*', - default=(), - help='files to check') - files_group.add_argument('-', action='store_true', dest='stdin', - help='read from standard input') + files_group.add_argument( + 'files', metavar='FILE_OR_DIR', nargs='*', default=(), help='files to check' + ) + files_group.add_argument( + '-', action='store_true', dest='stdin', help='read from standard input' + ) config_group = parser.add_mutually_exclusive_group() - config_group.add_argument('-c', '--config-file', dest='config_file', - action='store', - help='path to a custom configuration') - config_group.add_argument('-d', '--config-data', dest='config_data', - action='store', - help='custom configuration (as YAML source)') - parser.add_argument('--list-files', action='store_true', dest='list_files', - help='list files to lint and exit') - parser.add_argument('-f', '--format', - choices=('parsable', 'standard', 'colored', 'github', - 'auto'), - default='auto', help='format for parsing output') - parser.add_argument('-s', '--strict', - action='store_true', - help='return non-zero exit code on warnings ' - 'as well as errors') - parser.add_argument('--no-warnings', - action='store_true', - help='output only error level problems') - parser.add_argument('-v', '--version', action='version', - version=f'{APP_NAME} {APP_VERSION}') + config_group.add_argument( + '-c', + '--config-file', + dest='config_file', + action='store', + help='path to a custom configuration', + ) + config_group.add_argument( + '-d', + '--config-data', + dest='config_data', + action='store', + help='custom configuration (as YAML source)', + ) + parser.add_argument( + '--list-files', + action='store_true', + dest='list_files', + help='list files to lint and exit', + ) + parser.add_argument( + '-f', + '--format', + choices=('parsable', 'standard', 'colored', 'github', 'auto'), + default='auto', + help='format for parsing output', + ) + parser.add_argument( + '-s', + '--strict', + action='store_true', + help='return non-zero exit code on warnings ' 'as well as errors', + ) + parser.add_argument( + '--no-warnings', action='store_true', help='output only error level problems' + ) + parser.add_argument( + '-v', '--version', action='version', version=f'{APP_NAME} {APP_VERSION}' + ) args = parser.parse_args(argv) if 'YAMLLINT_CONFIG_FILE' in os.environ: - user_global_config = os.path.expanduser( - os.environ['YAMLLINT_CONFIG_FILE']) + user_global_config = os.path.expanduser(os.environ['YAMLLINT_CONFIG_FILE']) # User-global config is supposed to be in ~/.config/yamllint/config elif 'XDG_CONFIG_HOME' in os.environ: user_global_config = os.path.join( - os.environ['XDG_CONFIG_HOME'], 'yamllint', 'config') + os.environ['XDG_CONFIG_HOME'], 'yamllint', 'config' + ) else: user_global_config = os.path.expanduser('~/.config/yamllint/config') @@ -223,8 +246,9 @@ def run(argv=None): except OSError as e: print(e, file=sys.stderr) sys.exit(-1) - prob_level = show_problems(problems, file, args_format=args.format, - no_warn=args.no_warnings) + prob_level = show_problems( + problems, file, args_format=args.format, no_warn=args.no_warnings + ) max_level = max(max_level, prob_level) # read yaml from stdin @@ -234,8 +258,9 @@ def run(argv=None): except OSError as e: print(e, file=sys.stderr) sys.exit(-1) - prob_level = show_problems(problems, 'stdin', args_format=args.format, - no_warn=args.no_warnings) + prob_level = show_problems( + problems, 'stdin', args_format=args.format, no_warn=args.no_warnings + ) max_level = max(max_level, prob_level) if max_level == PROBLEM_LEVELS['error']: diff --git a/yamllint/config.py b/yamllint/config.py index 9ce62549..1ae6bb88 100644 --- a/yamllint/config.py +++ b/yamllint/config.py @@ -33,7 +33,8 @@ def __init__(self, content=None, file=None): self.ignore = None self.yaml_files = pathspec.PathSpec.from_lines( - 'gitwildmatch', ['*.yaml', '*.yml', '.yamllint']) + 'gitwildmatch', ['*.yaml', '*.yml', '.yamllint'] + ) self.locale = None @@ -51,18 +52,26 @@ def is_yaml_file(self, filepath): return self.yaml_files.match_file(os.path.basename(filepath)) def enabled_rules(self, filepath): - return [yamllint.rules.get(id) for id, val in self.rules.items() - if val is not False and ( - filepath is None or 'ignore' not in val or - not val['ignore'].match_file(filepath))] + return [ + yamllint.rules.get(id) + for id, val in self.rules.items() + if val is not False + and ( + filepath is None + or 'ignore' not in val + or not val['ignore'].match_file(filepath) + ) + ] def extend(self, base_config): assert isinstance(base_config, YamlLintConfig) for rule in self.rules: - if (isinstance(self.rules[rule], dict) and - rule in base_config.rules and - base_config.rules[rule] is not False): + if ( + isinstance(self.rules[rule], dict) + and rule in base_config.rules + and base_config.rules[rule] is not False + ): base_config.rules[rule].update(self.rules[rule]) else: base_config.rules[rule] = self.rules[rule] @@ -100,42 +109,52 @@ def parse(self, raw_content): if 'ignore' in conf and 'ignore-from-file' in conf: raise YamlLintConfigError( 'invalid config: ignore and ignore-from-file keys cannot be ' - 'used together') + 'used together' + ) elif 'ignore-from-file' in conf: if isinstance(conf['ignore-from-file'], str): conf['ignore-from-file'] = [conf['ignore-from-file']] - if not (isinstance(conf['ignore-from-file'], list) and all( - isinstance(ln, str) for ln in conf['ignore-from-file'])): + if not ( + isinstance(conf['ignore-from-file'], list) + and all(isinstance(ln, str) for ln in conf['ignore-from-file']) + ): raise YamlLintConfigError( 'invalid config: ignore-from-file should contain ' - 'filename(s), either as a list or string') + 'filename(s), either as a list or string' + ) with fileinput.input(conf['ignore-from-file']) as f: self.ignore = pathspec.PathSpec.from_lines('gitwildmatch', f) elif 'ignore' in conf: if isinstance(conf['ignore'], str): self.ignore = pathspec.PathSpec.from_lines( - 'gitwildmatch', conf['ignore'].splitlines()) - elif (isinstance(conf['ignore'], list) and - all(isinstance(line, str) for line in conf['ignore'])): + 'gitwildmatch', conf['ignore'].splitlines() + ) + elif isinstance(conf['ignore'], list) and all( + isinstance(line, str) for line in conf['ignore'] + ): self.ignore = pathspec.PathSpec.from_lines( - 'gitwildmatch', conf['ignore']) + 'gitwildmatch', conf['ignore'] + ) else: raise YamlLintConfigError( - 'invalid config: ignore should contain file patterns') + 'invalid config: ignore should contain file patterns' + ) if 'yaml-files' in conf: - if not (isinstance(conf['yaml-files'], list) - and all(isinstance(i, str) for i in conf['yaml-files'])): + if not ( + isinstance(conf['yaml-files'], list) + and all(isinstance(i, str) for i in conf['yaml-files']) + ): raise YamlLintConfigError( - 'invalid config: yaml-files ' - 'should be a list of file patterns') - self.yaml_files = pathspec.PathSpec.from_lines('gitwildmatch', - conf['yaml-files']) + 'invalid config: yaml-files ' 'should be a list of file patterns' + ) + self.yaml_files = pathspec.PathSpec.from_lines( + 'gitwildmatch', conf['yaml-files'] + ) if 'locale' in conf: if not isinstance(conf['locale'], str): - raise YamlLintConfigError( - 'invalid config: locale should be a string') + raise YamlLintConfigError('invalid config: locale should be a string') self.locale = conf['locale'] def validate(self): @@ -153,37 +172,45 @@ def validate_rule_conf(rule, conf): return False if isinstance(conf, dict): - if ('ignore-from-file' in conf and not isinstance( - conf['ignore-from-file'], pathspec.pathspec.PathSpec)): + if 'ignore-from-file' in conf and not isinstance( + conf['ignore-from-file'], pathspec.pathspec.PathSpec + ): if isinstance(conf['ignore-from-file'], str): conf['ignore-from-file'] = [conf['ignore-from-file']] - if not (isinstance(conf['ignore-from-file'], list) - and all(isinstance(line, str) - for line in conf['ignore-from-file'])): + if not ( + isinstance(conf['ignore-from-file'], list) + and all(isinstance(line, str) for line in conf['ignore-from-file']) + ): raise YamlLintConfigError( 'invalid config: ignore-from-file should contain ' - 'valid filename(s), either as a list or string') + 'valid filename(s), either as a list or string' + ) with fileinput.input(conf['ignore-from-file']) as f: - conf['ignore'] = pathspec.PathSpec.from_lines( - 'gitwildmatch', f) - elif ('ignore' in conf and not isinstance( - conf['ignore'], pathspec.pathspec.PathSpec)): + conf['ignore'] = pathspec.PathSpec.from_lines('gitwildmatch', f) + elif 'ignore' in conf and not isinstance( + conf['ignore'], pathspec.pathspec.PathSpec + ): if isinstance(conf['ignore'], str): conf['ignore'] = pathspec.PathSpec.from_lines( - 'gitwildmatch', conf['ignore'].splitlines()) - elif (isinstance(conf['ignore'], list) and - all(isinstance(line, str) for line in conf['ignore'])): + 'gitwildmatch', conf['ignore'].splitlines() + ) + elif isinstance(conf['ignore'], list) and all( + isinstance(line, str) for line in conf['ignore'] + ): conf['ignore'] = pathspec.PathSpec.from_lines( - 'gitwildmatch', conf['ignore']) + 'gitwildmatch', conf['ignore'] + ) else: raise YamlLintConfigError( - 'invalid config: ignore should contain file patterns') + 'invalid config: ignore should contain file patterns' + ) if 'level' not in conf: conf['level'] = 'error' elif conf['level'] not in ('error', 'warning'): raise YamlLintConfigError( - 'invalid config: level should be "error" or "warning"') + 'invalid config: level should be "error" or "warning"' + ) options = getattr(rule, 'CONF', {}) options_default = getattr(rule, 'DEFAULT', {}) @@ -193,32 +220,38 @@ def validate_rule_conf(rule, conf): if optkey not in options: raise YamlLintConfigError( f'invalid config: unknown option "{optkey}" for rule ' - f'"{rule.ID}"') + f'"{rule.ID}"' + ) # Example: CONF = {option: (bool, 'mixed')} # → {option: true} → {option: mixed} if isinstance(options[optkey], tuple): - if (conf[optkey] not in options[optkey] and - type(conf[optkey]) not in options[optkey]): + if ( + conf[optkey] not in options[optkey] + and type(conf[optkey]) not in options[optkey] + ): raise YamlLintConfigError( f'invalid config: option "{optkey}" of "{rule.ID}" ' - f'should be in {options[optkey]}') + f'should be in {options[optkey]}' + ) # Example: CONF = {option: ['flag1', 'flag2', int]} # → {option: [flag1]} → {option: [42, flag1, flag2]} elif isinstance(options[optkey], list): - if (not isinstance(conf[optkey], list) or - any(flag not in options[optkey] and - type(flag) not in options[optkey] - for flag in conf[optkey])): + if not isinstance(conf[optkey], list) or any( + flag not in options[optkey] and type(flag) not in options[optkey] + for flag in conf[optkey] + ): raise YamlLintConfigError( f'invalid config: option "{optkey}" of "{rule.ID}" ' - f'should only contain values in {options[optkey]}') + f'should only contain values in {options[optkey]}' + ) # Example: CONF = {option: int} # → {option: 42} else: if not isinstance(conf[optkey], options[optkey]): raise YamlLintConfigError( f'invalid config: option "{optkey}" of "{rule.ID}" ' - f'should be {options[optkey].__name__}') + f'should be {options[optkey].__name__}' + ) for optkey in options: if optkey not in conf: conf[optkey] = options_default[optkey] @@ -230,7 +263,8 @@ def validate_rule_conf(rule, conf): else: raise YamlLintConfigError( f'invalid config: rule "{rule.ID}": should be either "enable", ' - f'"disable" or a dict') + f'"disable" or a dict' + ) return conf @@ -238,8 +272,9 @@ def validate_rule_conf(rule, conf): def get_extended_config_file(name): # Is it a standard conf shipped with yamllint... if '/' not in name: - std_conf = os.path.join(os.path.dirname(os.path.realpath(__file__)), - 'conf', f'{name}.yaml') + std_conf = os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'conf', f'{name}.yaml' + ) if os.path.isfile(std_conf): return std_conf diff --git a/yamllint/linter.py b/yamllint/linter.py index a2faa061..8f8f9d13 100644 --- a/yamllint/linter.py +++ b/yamllint/linter.py @@ -35,6 +35,7 @@ class LintProblem: """Represents a linting problem found by yamllint.""" + def __init__(self, line, column, desc='', rule=None): #: Line on which the problem was found (starting at 1) self.line = line @@ -53,13 +54,16 @@ def message(self): return self.desc def __eq__(self, other): - return (self.line == other.line and - self.column == other.column and - self.rule == other.rule) + return ( + self.line == other.line + and self.column == other.column + and self.rule == other.rule + ) def __lt__(self, other): - return (self.line < other.line or - (self.line == other.line and self.column < other.column)) + return self.line < other.line or ( + self.line == other.line and self.column < other.column + ) def __repr__(self): return f'{self.line}:{self.column}: {self.message}' @@ -133,10 +137,14 @@ def process_comment(self, comment): if isinstance(elem, parser.Token): for rule in token_rules: rule_conf = conf.rules[rule.ID] - for problem in rule.check(rule_conf, - elem.curr, elem.prev, elem.next, - elem.nextnext, - context[rule.ID]): + for problem in rule.check( + rule_conf, + elem.curr, + elem.prev, + elem.next, + elem.nextnext, + context[rule.ID], + ): problem.rule = rule.ID problem.level = rule_conf['level'] cache.append(problem) @@ -164,8 +172,10 @@ def process_comment(self, comment): # This is the last token/comment/line of this line, let's flush the # problems found (but filter them according to the directives) for problem in cache: - if not (disabled_for_line.is_disabled_by_directive(problem) or - disabled.is_disabled_by_directive(problem)): + if not ( + disabled_for_line.is_disabled_by_directive(problem) + or disabled.is_disabled_by_directive(problem) + ): yield problem disabled_for_line = disabled_for_next_line @@ -177,16 +187,19 @@ def get_syntax_error(buffer): try: list(yaml.parse(buffer, Loader=yaml.BaseLoader)) except yaml.error.MarkedYAMLError as e: - problem = LintProblem(e.problem_mark.line + 1, - e.problem_mark.column + 1, - 'syntax error: ' + e.problem + ' (syntax)') + problem = LintProblem( + e.problem_mark.line + 1, + e.problem_mark.column + 1, + 'syntax error: ' + e.problem + ' (syntax)', + ) problem.level = 'error' return problem def _run(buffer, conf, filepath): - assert hasattr(buffer, '__getitem__'), \ - '_run() argument must be a buffer, not a stream' + assert hasattr( + buffer, '__getitem__' + ), '_run() argument must be a buffer, not a stream' first_line = next(parser.line_generator(buffer)).content if re.match(r'^#\s*yamllint disable-file\s*$', first_line): @@ -198,8 +211,11 @@ def _run(buffer, conf, filepath): for problem in get_cosmetic_problems(buffer, conf, filepath): # Insert the syntax error (if any) at the right place... - if (syntax_error and syntax_error.line <= problem.line and - syntax_error.column <= problem.column): + if ( + syntax_error + and syntax_error.line <= problem.line + and syntax_error.column <= problem.column + ): yield syntax_error # Discard the problem since it is at the same place as the syntax diff --git a/yamllint/parser.py b/yamllint/parser.py index f0ee3a63..158e3967 100644 --- a/yamllint/parser.py +++ b/yamllint/parser.py @@ -25,7 +25,7 @@ def __init__(self, line_no, buffer, start, end): @property def content(self): - return self.buffer[self.start:self.end] + return self.buffer[self.start : self.end] class Token: @@ -38,8 +38,16 @@ def __init__(self, line_no, curr, prev, next, nextnext): class Comment: - def __init__(self, line_no, column_no, buffer, pointer, - token_before=None, token_after=None, comment_before=None): + def __init__( + self, + line_no, + column_no, + buffer, + pointer, + token_before=None, + token_after=None, + comment_before=None, + ): self.line_no = line_no self.column_no = column_no self.buffer = buffer @@ -53,19 +61,22 @@ def __str__(self): if end == -1: end = self.buffer.find('\0', self.pointer) if end != -1: - return self.buffer[self.pointer:end] - return self.buffer[self.pointer:] + return self.buffer[self.pointer : end] + return self.buffer[self.pointer :] def __eq__(self, other): - return (isinstance(other, Comment) and - self.line_no == other.line_no and - self.column_no == other.column_no and - str(self) == str(other)) + return ( + isinstance(other, Comment) + and self.line_no == other.line_no + and self.column_no == other.column_no + and str(self) == str(other) + ) def is_inline(self): return ( - not isinstance(self.token_before, yaml.StreamStartToken) and - self.line_no == self.token_before.end_mark.line + 1 and + not isinstance(self.token_before, yaml.StreamStartToken) + and self.line_no == self.token_before.end_mark.line + 1 + and # sometimes token end marks are on the next line self.buffer[self.token_before.end_mark.pointer - 1] != '\n' ) @@ -90,14 +101,17 @@ def line_generator(buffer): def comments_between_tokens(token1, token2): """Find all comments between two tokens""" if token2 is None: - buf = token1.end_mark.buffer[token1.end_mark.pointer:] - elif (token1.end_mark.line == token2.start_mark.line and - not isinstance(token1, yaml.StreamStartToken) and - not isinstance(token2, yaml.StreamEndToken)): + buf = token1.end_mark.buffer[token1.end_mark.pointer :] + elif ( + token1.end_mark.line == token2.start_mark.line + and not isinstance(token1, yaml.StreamStartToken) + and not isinstance(token2, yaml.StreamEndToken) + ): return else: - buf = token1.end_mark.buffer[token1.end_mark.pointer: - token2.start_mark.pointer] + buf = token1.end_mark.buffer[ + token1.end_mark.pointer : token2.start_mark.pointer + ] line_no = token1.end_mark.line + 1 column_no = token1.end_mark.column + 1 @@ -107,9 +121,15 @@ def comments_between_tokens(token1, token2): for line in buf.split('\n'): pos = line.find('#') if pos != -1: - comment = Comment(line_no, column_no + pos, - token1.end_mark.buffer, pointer + pos, - token1, token2, comment_before) + comment = Comment( + line_no, + column_no + pos, + token1.end_mark.buffer, + pointer + pos, + token1, + token2, + comment_before, + ) yield comment comment_before = comment @@ -127,8 +147,7 @@ def token_or_comment_generator(buffer): curr = yaml_loader.get_token() while curr is not None: next = yaml_loader.get_token() - nextnext = (yaml_loader.peek_token() - if yaml_loader.check_token() else None) + nextnext = yaml_loader.peek_token() if yaml_loader.check_token() else None yield Token(curr.start_mark.line + 1, curr, prev, next, nextnext) @@ -150,8 +169,9 @@ def token_or_comment_or_line_generator(buffer): line = next(line_gen, None) while tok_or_com is not None or line is not None: - if tok_or_com is None or (line is not None and - tok_or_com.line_no > line.line_no): + if tok_or_com is None or ( + line is not None and tok_or_com.line_no > line.line_no + ): yield line line = next(line_gen, None) else: diff --git a/yamllint/rules/anchors.py b/yamllint/rules/anchors.py index d968461f..016aa749 100644 --- a/yamllint/rules/anchors.py +++ b/yamllint/rules/anchors.py @@ -110,37 +110,51 @@ ID = 'anchors' TYPE = 'token' -CONF = {'forbid-undeclared-aliases': bool, - 'forbid-duplicated-anchors': bool, - 'forbid-unused-anchors': bool} -DEFAULT = {'forbid-undeclared-aliases': True, - 'forbid-duplicated-anchors': False, - 'forbid-unused-anchors': False} +CONF = { + 'forbid-undeclared-aliases': bool, + 'forbid-duplicated-anchors': bool, + 'forbid-unused-anchors': bool, +} +DEFAULT = { + 'forbid-undeclared-aliases': True, + 'forbid-duplicated-anchors': False, + 'forbid-unused-anchors': False, +} def check(conf, token, prev, next, nextnext, context): - if (conf['forbid-undeclared-aliases'] or - conf['forbid-duplicated-anchors'] or - conf['forbid-unused-anchors']): - if isinstance(token, ( - yaml.StreamStartToken, - yaml.DocumentStartToken, - yaml.DocumentEndToken)): + if ( + conf['forbid-undeclared-aliases'] + or conf['forbid-duplicated-anchors'] + or conf['forbid-unused-anchors'] + ): + if isinstance( + token, + (yaml.StreamStartToken, yaml.DocumentStartToken, yaml.DocumentEndToken), + ): context['anchors'] = {} - if (conf['forbid-undeclared-aliases'] and - isinstance(token, yaml.AliasToken) and - token.value not in context['anchors']): + if ( + conf['forbid-undeclared-aliases'] + and isinstance(token, yaml.AliasToken) + and token.value not in context['anchors'] + ): yield LintProblem( - token.start_mark.line + 1, token.start_mark.column + 1, - f'found undeclared alias "{token.value}"') - - if (conf['forbid-duplicated-anchors'] and - isinstance(token, yaml.AnchorToken) and - token.value in context['anchors']): + token.start_mark.line + 1, + token.start_mark.column + 1, + f'found undeclared alias "{token.value}"', + ) + + if ( + conf['forbid-duplicated-anchors'] + and isinstance(token, yaml.AnchorToken) + and token.value in context['anchors'] + ): yield LintProblem( - token.start_mark.line + 1, token.start_mark.column + 1, - f'found duplicated anchor "{token.value}"') + token.start_mark.line + 1, + token.start_mark.column + 1, + f'found duplicated anchor "{token.value}"', + ) if conf['forbid-unused-anchors']: # Unused anchors can only be detected at the end of Document. @@ -151,23 +165,27 @@ def check(conf, token, prev, next, nextnext, context): # If next token indicates end of document, # check if the anchors have been used or not. # If they haven't been used, report problem on those anchors. - if isinstance(next, (yaml.StreamEndToken, - yaml.DocumentStartToken, - yaml.DocumentEndToken)): + if isinstance( + next, (yaml.StreamEndToken, yaml.DocumentStartToken, yaml.DocumentEndToken) + ): for anchor, info in context['anchors'].items(): if not info['used']: - yield LintProblem(info['line'] + 1, - info['column'] + 1, - f'found unused anchor "{anchor}"') + yield LintProblem( + info['line'] + 1, + info['column'] + 1, + f'found unused anchor "{anchor}"', + ) elif isinstance(token, yaml.AliasToken): context['anchors'].get(token.value, {})['used'] = True - if (conf['forbid-undeclared-aliases'] or - conf['forbid-duplicated-anchors'] or - conf['forbid-unused-anchors']): + if ( + conf['forbid-undeclared-aliases'] + or conf['forbid-duplicated-anchors'] + or conf['forbid-unused-anchors'] + ): if isinstance(token, yaml.AnchorToken): context['anchors'][token.value] = { 'line': token.start_mark.line, 'column': token.start_mark.column, - 'used': False + 'used': False, } diff --git a/yamllint/rules/braces.py b/yamllint/rules/braces.py index 19f870a1..82b0aef8 100644 --- a/yamllint/rules/braces.py +++ b/yamllint/rules/braces.py @@ -139,62 +139,88 @@ ID = 'braces' TYPE = 'token' -CONF = {'forbid': (bool, 'non-empty'), - 'min-spaces-inside': int, - 'max-spaces-inside': int, - 'min-spaces-inside-empty': int, - 'max-spaces-inside-empty': int} -DEFAULT = {'forbid': False, - 'min-spaces-inside': 0, - 'max-spaces-inside': 0, - 'min-spaces-inside-empty': -1, - 'max-spaces-inside-empty': -1} +CONF = { + 'forbid': (bool, 'non-empty'), + 'min-spaces-inside': int, + 'max-spaces-inside': int, + 'min-spaces-inside-empty': int, + 'max-spaces-inside-empty': int, +} +DEFAULT = { + 'forbid': False, + 'min-spaces-inside': 0, + 'max-spaces-inside': 0, + 'min-spaces-inside-empty': -1, + 'max-spaces-inside-empty': -1, +} def check(conf, token, prev, next, nextnext, context): - if (conf['forbid'] is True and - isinstance(token, yaml.FlowMappingStartToken)): - yield LintProblem(token.start_mark.line + 1, - token.end_mark.column + 1, - 'forbidden flow mapping') - - elif (conf['forbid'] == 'non-empty' and - isinstance(token, yaml.FlowMappingStartToken) and - not isinstance(next, yaml.FlowMappingEndToken)): - yield LintProblem(token.start_mark.line + 1, - token.end_mark.column + 1, - 'forbidden flow mapping') - - elif (isinstance(token, yaml.FlowMappingStartToken) and - isinstance(next, yaml.FlowMappingEndToken)): - problem = spaces_after(token, prev, next, - min=(conf['min-spaces-inside-empty'] - if conf['min-spaces-inside-empty'] != -1 - else conf['min-spaces-inside']), - max=(conf['max-spaces-inside-empty'] - if conf['max-spaces-inside-empty'] != -1 - else conf['max-spaces-inside']), - min_desc='too few spaces inside empty braces', - max_desc='too many spaces inside empty braces') + if conf['forbid'] is True and isinstance(token, yaml.FlowMappingStartToken): + yield LintProblem( + token.start_mark.line + 1, + token.end_mark.column + 1, + 'forbidden flow mapping', + ) + + elif ( + conf['forbid'] == 'non-empty' + and isinstance(token, yaml.FlowMappingStartToken) + and not isinstance(next, yaml.FlowMappingEndToken) + ): + yield LintProblem( + token.start_mark.line + 1, + token.end_mark.column + 1, + 'forbidden flow mapping', + ) + + elif isinstance(token, yaml.FlowMappingStartToken) and isinstance( + next, yaml.FlowMappingEndToken + ): + problem = spaces_after( + token, + prev, + next, + min=( + conf['min-spaces-inside-empty'] + if conf['min-spaces-inside-empty'] != -1 + else conf['min-spaces-inside'] + ), + max=( + conf['max-spaces-inside-empty'] + if conf['max-spaces-inside-empty'] != -1 + else conf['max-spaces-inside'] + ), + min_desc='too few spaces inside empty braces', + max_desc='too many spaces inside empty braces', + ) if problem is not None: yield problem elif 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') + 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') + 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 diff --git a/yamllint/rules/brackets.py b/yamllint/rules/brackets.py index f1c08d5a..7beede92 100644 --- a/yamllint/rules/brackets.py +++ b/yamllint/rules/brackets.py @@ -140,63 +140,88 @@ ID = 'brackets' TYPE = 'token' -CONF = {'forbid': (bool, 'non-empty'), - 'min-spaces-inside': int, - 'max-spaces-inside': int, - 'min-spaces-inside-empty': int, - 'max-spaces-inside-empty': int} -DEFAULT = {'forbid': False, - 'min-spaces-inside': 0, - 'max-spaces-inside': 0, - 'min-spaces-inside-empty': -1, - 'max-spaces-inside-empty': -1} +CONF = { + 'forbid': (bool, 'non-empty'), + 'min-spaces-inside': int, + 'max-spaces-inside': int, + 'min-spaces-inside-empty': int, + 'max-spaces-inside-empty': int, +} +DEFAULT = { + 'forbid': False, + 'min-spaces-inside': 0, + 'max-spaces-inside': 0, + 'min-spaces-inside-empty': -1, + 'max-spaces-inside-empty': -1, +} def check(conf, token, prev, next, nextnext, context): - if (conf['forbid'] is True and - isinstance(token, yaml.FlowSequenceStartToken)): - yield LintProblem(token.start_mark.line + 1, - token.end_mark.column + 1, - 'forbidden flow sequence') - - elif (conf['forbid'] == 'non-empty' and - isinstance(token, yaml.FlowSequenceStartToken) and - not isinstance(next, yaml.FlowSequenceEndToken)): - yield LintProblem(token.start_mark.line + 1, - token.end_mark.column + 1, - 'forbidden flow sequence') - - elif (isinstance(token, yaml.FlowSequenceStartToken) and - isinstance(next, yaml.FlowSequenceEndToken)): - problem = spaces_after(token, prev, next, - min=(conf['min-spaces-inside-empty'] - if conf['min-spaces-inside-empty'] != -1 - else conf['min-spaces-inside']), - max=(conf['max-spaces-inside-empty'] - if conf['max-spaces-inside-empty'] != -1 - else conf['max-spaces-inside']), - min_desc='too few spaces inside empty brackets', - max_desc=('too many spaces inside empty ' - 'brackets')) + if conf['forbid'] is True and isinstance(token, yaml.FlowSequenceStartToken): + yield LintProblem( + token.start_mark.line + 1, + token.end_mark.column + 1, + 'forbidden flow sequence', + ) + + elif ( + conf['forbid'] == 'non-empty' + and isinstance(token, yaml.FlowSequenceStartToken) + and not isinstance(next, yaml.FlowSequenceEndToken) + ): + yield LintProblem( + token.start_mark.line + 1, + token.end_mark.column + 1, + 'forbidden flow sequence', + ) + + elif isinstance(token, yaml.FlowSequenceStartToken) and isinstance( + next, yaml.FlowSequenceEndToken + ): + problem = spaces_after( + token, + prev, + next, + min=( + conf['min-spaces-inside-empty'] + if conf['min-spaces-inside-empty'] != -1 + else conf['min-spaces-inside'] + ), + max=( + conf['max-spaces-inside-empty'] + if conf['max-spaces-inside-empty'] != -1 + else conf['max-spaces-inside'] + ), + min_desc='too few spaces inside empty brackets', + max_desc=('too many spaces inside empty ' 'brackets'), + ) if problem is not None: yield problem elif isinstance(token, yaml.FlowSequenceStartToken): - problem = spaces_after(token, prev, next, - min=conf['min-spaces-inside'], - max=conf['max-spaces-inside'], - min_desc='too few spaces inside brackets', - max_desc='too many spaces inside brackets') + problem = spaces_after( + token, + prev, + next, + min=conf['min-spaces-inside'], + max=conf['max-spaces-inside'], + min_desc='too few spaces inside brackets', + max_desc='too many spaces inside brackets', + ) if problem is not None: yield problem - elif (isinstance(token, yaml.FlowSequenceEndToken) and - (prev is None or - not isinstance(prev, yaml.FlowSequenceStartToken))): - problem = spaces_before(token, prev, next, - min=conf['min-spaces-inside'], - max=conf['max-spaces-inside'], - min_desc='too few spaces inside brackets', - max_desc='too many spaces inside brackets') + elif isinstance(token, yaml.FlowSequenceEndToken) and ( + prev is None or not isinstance(prev, yaml.FlowSequenceStartToken) + ): + problem = spaces_before( + token, + prev, + next, + min=conf['min-spaces-inside'], + max=conf['max-spaces-inside'], + min_desc='too few spaces inside brackets', + max_desc='too many spaces inside brackets', + ) if problem is not None: yield problem diff --git a/yamllint/rules/colons.py b/yamllint/rules/colons.py index 2a181c66..080cea39 100644 --- a/yamllint/rules/colons.py +++ b/yamllint/rules/colons.py @@ -84,31 +84,42 @@ ID = 'colons' TYPE = 'token' -CONF = {'max-spaces-before': int, - 'max-spaces-after': int} -DEFAULT = {'max-spaces-before': 0, - 'max-spaces-after': 1} +CONF = {'max-spaces-before': int, 'max-spaces-after': int} +DEFAULT = {'max-spaces-before': 0, 'max-spaces-after': 1} def check(conf, token, prev, next, nextnext, context): if isinstance(token, yaml.ValueToken) and not ( - isinstance(prev, yaml.AliasToken) and - token.start_mark.pointer - prev.end_mark.pointer == 1): - problem = spaces_before(token, prev, next, - max=conf['max-spaces-before'], - max_desc='too many spaces before colon') + isinstance(prev, yaml.AliasToken) + and token.start_mark.pointer - prev.end_mark.pointer == 1 + ): + problem = spaces_before( + token, + prev, + next, + max=conf['max-spaces-before'], + max_desc='too many spaces before colon', + ) if problem is not None: yield problem - problem = spaces_after(token, prev, next, - max=conf['max-spaces-after'], - max_desc='too many spaces after colon') + problem = spaces_after( + token, + prev, + next, + max=conf['max-spaces-after'], + max_desc='too many spaces after colon', + ) if problem is not None: yield problem if isinstance(token, yaml.KeyToken) and is_explicit_key(token): - problem = spaces_after(token, prev, next, - max=conf['max-spaces-after'], - max_desc='too many spaces after question mark') + problem = spaces_after( + token, + prev, + next, + max=conf['max-spaces-after'], + max_desc='too many spaces after question mark', + ) if problem is not None: yield problem diff --git a/yamllint/rules/commas.py b/yamllint/rules/commas.py index baa8b7dd..6094b034 100644 --- a/yamllint/rules/commas.py +++ b/yamllint/rules/commas.py @@ -108,32 +108,41 @@ ID = 'commas' TYPE = 'token' -CONF = {'max-spaces-before': int, - 'min-spaces-after': int, - 'max-spaces-after': int} -DEFAULT = {'max-spaces-before': 0, - 'min-spaces-after': 1, - 'max-spaces-after': 1} +CONF = {'max-spaces-before': int, 'min-spaces-after': int, 'max-spaces-after': int} +DEFAULT = {'max-spaces-before': 0, 'min-spaces-after': 1, 'max-spaces-after': 1} def check(conf, token, prev, next, nextnext, context): if isinstance(token, yaml.FlowEntryToken): - 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') + 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', + ) else: - problem = spaces_before(token, prev, next, - max=conf['max-spaces-before'], - max_desc='too many spaces before comma') + problem = spaces_before( + token, + prev, + next, + max=conf['max-spaces-before'], + max_desc='too many spaces before comma', + ) if problem is not None: 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') + 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 diff --git a/yamllint/rules/comments.py b/yamllint/rules/comments.py index 7e4f04c1..3988d2a7 100644 --- a/yamllint/rules/comments.py +++ b/yamllint/rules/comments.py @@ -77,36 +77,45 @@ ID = 'comments' TYPE = 'comment' -CONF = {'require-starting-space': bool, - 'ignore-shebangs': bool, - 'min-spaces-from-content': int} -DEFAULT = {'require-starting-space': True, - 'ignore-shebangs': True, - 'min-spaces-from-content': 2} +CONF = { + 'require-starting-space': bool, + 'ignore-shebangs': bool, + 'min-spaces-from-content': int, +} +DEFAULT = { + 'require-starting-space': True, + 'ignore-shebangs': True, + 'min-spaces-from-content': 2, +} def check(conf, comment): - if (conf['min-spaces-from-content'] != -1 and comment.is_inline() and - comment.pointer - comment.token_before.end_mark.pointer < - conf['min-spaces-from-content']): - yield LintProblem(comment.line_no, comment.column_no, - 'too few spaces before comment') + if ( + conf['min-spaces-from-content'] != -1 + and comment.is_inline() + and comment.pointer - comment.token_before.end_mark.pointer + < conf['min-spaces-from-content'] + ): + yield LintProblem( + comment.line_no, comment.column_no, 'too few spaces before comment' + ) if conf['require-starting-space']: text_start = comment.pointer + 1 - while (comment.buffer[text_start] == '#' and - text_start < len(comment.buffer)): + while comment.buffer[text_start] == '#' and text_start < len(comment.buffer): text_start += 1 if text_start < len(comment.buffer): - if (conf['ignore-shebangs'] and - comment.line_no == 1 and - comment.column_no == 1 and - comment.buffer[text_start] == '!'): + if ( + conf['ignore-shebangs'] + and comment.line_no == 1 + and comment.column_no == 1 + and comment.buffer[text_start] == '!' + ): return # We can test for both \r and \r\n just by checking first char # \r itself is a valid newline on some older OS. elif comment.buffer[text_start] not in {' ', '\n', '\r', '\x00'}: column = comment.column_no + text_start - comment.pointer - yield LintProblem(comment.line_no, - column, - 'missing starting space in comment') + yield LintProblem( + comment.line_no, column, 'missing starting space in comment' + ) diff --git a/yamllint/rules/comments_indentation.py b/yamllint/rules/comments_indentation.py index 8bcda4d2..a990ab18 100644 --- a/yamllint/rules/comments_indentation.py +++ b/yamllint/rules/comments_indentation.py @@ -96,10 +96,13 @@ # # commented line 2 # current: line + def check(conf, comment): # Only check block comments - if (not isinstance(comment.token_before, yaml.StreamStartToken) and - comment.token_before.end_mark.line + 1 == comment.line_no): + if ( + not isinstance(comment.token_before, yaml.StreamStartToken) + and comment.token_before.end_mark.line + 1 == comment.line_no + ): return next_line_indent = comment.token_after.start_mark.column @@ -126,11 +129,13 @@ def check(conf, comment): # # comment on valid indent (4) # other-list: # - 2 - if (comment.comment_before is not None and - not comment.comment_before.is_inline()): + if comment.comment_before is not None and not comment.comment_before.is_inline(): prev_line_indent = comment.comment_before.column_no - 1 - if (comment.column_no - 1 != prev_line_indent and - comment.column_no - 1 != next_line_indent): - yield LintProblem(comment.line_no, comment.column_no, - 'comment not indented like content') + if ( + comment.column_no - 1 != prev_line_indent + and comment.column_no - 1 != next_line_indent + ): + yield LintProblem( + comment.line_no, comment.column_no, 'comment not indented like content' + ) diff --git a/yamllint/rules/common.py b/yamllint/rules/common.py index 06f560c0..a4f00d1b 100644 --- a/yamllint/rules/common.py +++ b/yamllint/rules/common.py @@ -20,37 +20,44 @@ from yamllint.linter import LintProblem -def spaces_after(token, prev, next, min=-1, max=-1, - min_desc=None, max_desc=None): +def spaces_after(token, prev, next, min=-1, max=-1, min_desc=None, max_desc=None): if next is not None and token.end_mark.line == next.start_mark.line: spaces = next.start_mark.pointer - token.end_mark.pointer - if max != - 1 and spaces > max: - return LintProblem(token.start_mark.line + 1, - next.start_mark.column, max_desc) - elif min != - 1 and spaces < min: - return LintProblem(token.start_mark.line + 1, - next.start_mark.column + 1, min_desc) - - -def spaces_before(token, prev, next, min=-1, max=-1, - min_desc=None, max_desc=None): - if (prev is not None and prev.end_mark.line == token.start_mark.line and - # Discard tokens (only scalars?) that end at the start of next line - (prev.end_mark.pointer == 0 or - prev.end_mark.buffer[prev.end_mark.pointer - 1] != '\n')): + if max != -1 and spaces > max: + return LintProblem( + token.start_mark.line + 1, next.start_mark.column, max_desc + ) + elif min != -1 and spaces < min: + return LintProblem( + token.start_mark.line + 1, next.start_mark.column + 1, min_desc + ) + + +def spaces_before(token, prev, next, min=-1, max=-1, min_desc=None, max_desc=None): + if ( + prev is not None + and prev.end_mark.line == token.start_mark.line + and + # Discard tokens (only scalars?) that end at the start of next line + ( + prev.end_mark.pointer == 0 + or prev.end_mark.buffer[prev.end_mark.pointer - 1] != '\n' + ) + ): spaces = token.start_mark.pointer - prev.end_mark.pointer - if max != - 1 and spaces > max: - return LintProblem(token.start_mark.line + 1, - token.start_mark.column, max_desc) - elif min != - 1 and spaces < min: - return LintProblem(token.start_mark.line + 1, - token.start_mark.column + 1, min_desc) + if max != -1 and spaces > max: + return LintProblem( + token.start_mark.line + 1, token.start_mark.column, max_desc + ) + elif min != -1 and spaces < min: + return LintProblem( + token.start_mark.line + 1, token.start_mark.column + 1, min_desc + ) def get_line_indent(token): """Finds the indent of the line the token starts in.""" - start = token.start_mark.buffer.rfind('\n', 0, - token.start_mark.pointer) + 1 + start = token.start_mark.buffer.rfind('\n', 0, token.start_mark.pointer) + 1 content = start while token.start_mark.buffer[content] == ' ': content += 1 @@ -68,8 +75,10 @@ def get_real_end_line(token): return end_line pos = token.end_mark.pointer - 1 - while (pos >= token.start_mark.pointer - 1 and - token.end_mark.buffer[pos] in string.whitespace): + while ( + pos >= token.start_mark.pointer - 1 + and token.end_mark.buffer[pos] in string.whitespace + ): if token.end_mark.buffer[pos] == '\n': end_line -= 1 pos -= 1 @@ -84,5 +93,7 @@ def is_explicit_key(token): # ? # key # : v - return (token.start_mark.pointer < token.end_mark.pointer and - token.start_mark.buffer[token.start_mark.pointer] == '?') + return ( + token.start_mark.pointer < token.end_mark.pointer + and token.start_mark.buffer[token.start_mark.pointer] == '?' + ) diff --git a/yamllint/rules/document_end.py b/yamllint/rules/document_end.py index e1ce2a14..f3f55306 100644 --- a/yamllint/rules/document_end.py +++ b/yamllint/rules/document_end.py @@ -101,15 +101,16 @@ def check(conf, token, prev, next, nextnext, context): prev_is_directive = isinstance(prev, yaml.DirectiveToken) if is_stream_end and not prev_is_end_or_stream_start: - yield LintProblem(token.start_mark.line, 1, - 'missing document end "..."') - elif is_start and not (prev_is_end_or_stream_start - or prev_is_directive): - yield LintProblem(token.start_mark.line + 1, 1, - 'missing document end "..."') + yield LintProblem(token.start_mark.line, 1, 'missing document end "..."') + elif is_start and not (prev_is_end_or_stream_start or prev_is_directive): + yield LintProblem( + token.start_mark.line + 1, 1, 'missing document end "..."' + ) else: if isinstance(token, yaml.DocumentEndToken): - yield LintProblem(token.start_mark.line + 1, - token.start_mark.column + 1, - 'found forbidden document end "..."') + yield LintProblem( + token.start_mark.line + 1, + token.start_mark.column + 1, + 'found forbidden document end "..."', + ) diff --git a/yamllint/rules/document_start.py b/yamllint/rules/document_start.py index 225d7c3d..82626df0 100644 --- a/yamllint/rules/document_start.py +++ b/yamllint/rules/document_start.py @@ -83,17 +83,19 @@ def check(conf, token, prev, next, nextnext, context): if conf['present']: - if (isinstance(prev, (yaml.StreamStartToken, - yaml.DocumentEndToken, - yaml.DirectiveToken)) and - not isinstance(token, (yaml.DocumentStartToken, - yaml.DirectiveToken, - yaml.StreamEndToken))): - yield LintProblem(token.start_mark.line + 1, 1, - 'missing document start "---"') + if isinstance( + prev, (yaml.StreamStartToken, yaml.DocumentEndToken, yaml.DirectiveToken) + ) and not isinstance( + token, (yaml.DocumentStartToken, yaml.DirectiveToken, yaml.StreamEndToken) + ): + yield LintProblem( + token.start_mark.line + 1, 1, 'missing document start "---"' + ) else: if isinstance(token, yaml.DocumentStartToken): - yield LintProblem(token.start_mark.line + 1, - token.start_mark.column + 1, - 'found forbidden document start "---"') + yield LintProblem( + token.start_mark.line + 1, + token.start_mark.column + 1, + 'found forbidden document start "---"', + ) diff --git a/yamllint/rules/empty_lines.py b/yamllint/rules/empty_lines.py index 7ccbedf0..a7e6ed3e 100644 --- a/yamllint/rules/empty_lines.py +++ b/yamllint/rules/empty_lines.py @@ -63,28 +63,28 @@ ID = 'empty-lines' TYPE = 'line' -CONF = {'max': int, - 'max-start': int, - 'max-end': int} -DEFAULT = {'max': 2, - 'max-start': 0, - 'max-end': 0} +CONF = {'max': int, 'max-start': int, 'max-end': int} +DEFAULT = {'max': 2, 'max-start': 0, 'max-end': 0} def check(conf, line): if line.start == line.end and line.end < len(line.buffer): # Only alert on the last blank line of a series - if (line.end + 2 <= len(line.buffer) and - line.buffer[line.end:line.end + 2] == '\n\n'): + if ( + line.end + 2 <= len(line.buffer) + and line.buffer[line.end : line.end + 2] == '\n\n' + ): return - elif (line.end + 4 <= len(line.buffer) and - line.buffer[line.end:line.end + 4] == '\r\n\r\n'): + elif ( + line.end + 4 <= len(line.buffer) + and line.buffer[line.end : line.end + 4] == '\r\n\r\n' + ): return blank_lines = 0 start = line.start - while start >= 2 and line.buffer[start - 2:start] == '\r\n': + while start >= 2 and line.buffer[start - 2 : start] == '\r\n': blank_lines += 1 start -= 2 while start >= 1 and line.buffer[start - 1] == '\n': @@ -101,10 +101,10 @@ def check(conf, line): # Special case: end of document # NOTE: The last line of a file is always supposed to end with a new # line. See POSIX definition of a line at: - if ((line.end == len(line.buffer) - 1 and - line.buffer[line.end] == '\n') or - (line.end == len(line.buffer) - 2 and - line.buffer[line.end:line.end + 2] == '\r\n')): + if (line.end == len(line.buffer) - 1 and line.buffer[line.end] == '\n') or ( + line.end == len(line.buffer) - 2 + and line.buffer[line.end : line.end + 2] == '\r\n' + ): # Allow the exception of the one-byte file containing '\n' if line.end == 0: return @@ -112,5 +112,6 @@ def check(conf, line): max = conf['max-end'] if blank_lines > max: - yield LintProblem(line.line_no, 1, - f'too many blank lines ({blank_lines} > {max})') + yield LintProblem( + line.line_no, 1, f'too many blank lines ({blank_lines} > {max})' + ) diff --git a/yamllint/rules/empty_values.py b/yamllint/rules/empty_values.py index c1ff4f20..560ca330 100644 --- a/yamllint/rules/empty_values.py +++ b/yamllint/rules/empty_values.py @@ -107,33 +107,45 @@ ID = 'empty-values' TYPE = 'token' -CONF = {'forbid-in-block-mappings': bool, - 'forbid-in-flow-mappings': bool, - 'forbid-in-block-sequences': bool} -DEFAULT = {'forbid-in-block-mappings': True, - 'forbid-in-flow-mappings': True, - 'forbid-in-block-sequences': True} +CONF = { + 'forbid-in-block-mappings': bool, + 'forbid-in-flow-mappings': bool, + 'forbid-in-block-sequences': bool, +} +DEFAULT = { + 'forbid-in-block-mappings': True, + 'forbid-in-flow-mappings': True, + 'forbid-in-block-sequences': True, +} def check(conf, token, prev, next, nextnext, context): - if conf['forbid-in-block-mappings']: - if isinstance(token, yaml.ValueToken) and isinstance(next, ( - yaml.KeyToken, yaml.BlockEndToken)): - yield LintProblem(token.start_mark.line + 1, - token.end_mark.column + 1, - 'empty value in block mapping') + if isinstance(token, yaml.ValueToken) and isinstance( + next, (yaml.KeyToken, yaml.BlockEndToken) + ): + yield LintProblem( + token.start_mark.line + 1, + token.end_mark.column + 1, + 'empty value in block mapping', + ) if conf['forbid-in-flow-mappings']: - if isinstance(token, yaml.ValueToken) and isinstance(next, ( - yaml.FlowEntryToken, yaml.FlowMappingEndToken)): - yield LintProblem(token.start_mark.line + 1, - token.end_mark.column + 1, - 'empty value in flow mapping') + if isinstance(token, yaml.ValueToken) and isinstance( + next, (yaml.FlowEntryToken, yaml.FlowMappingEndToken) + ): + yield LintProblem( + token.start_mark.line + 1, + token.end_mark.column + 1, + 'empty value in flow mapping', + ) if conf['forbid-in-block-sequences']: - if isinstance(token, yaml.BlockEntryToken) and isinstance(next, ( - yaml.KeyToken, yaml.BlockEndToken, yaml.BlockEntryToken)): - yield LintProblem(token.start_mark.line + 1, - token.end_mark.column + 1, - 'empty value in block sequence') + if isinstance(token, yaml.BlockEntryToken) and isinstance( + next, (yaml.KeyToken, yaml.BlockEndToken, yaml.BlockEntryToken) + ): + yield LintProblem( + token.start_mark.line + 1, + token.end_mark.column + 1, + 'empty value in block sequence', + ) diff --git a/yamllint/rules/float_values.py b/yamllint/rules/float_values.py index 77a243bf..43f00b01 100644 --- a/yamllint/rules/float_values.py +++ b/yamllint/rules/float_values.py @@ -105,9 +105,7 @@ 'forbid-inf': False, } -IS_NUMERAL_BEFORE_DECIMAL_PATTERN = ( - re.compile('[-+]?(\\.[0-9]+)([eE][-+]?[0-9]+)?$') -) +IS_NUMERAL_BEFORE_DECIMAL_PATTERN = re.compile('[-+]?(\\.[0-9]+)([eE][-+]?[0-9]+)?$') IS_SCIENTIFIC_NOTATION_PATTERN = re.compile( '[-+]?(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)$' ) @@ -138,9 +136,7 @@ def check(conf, token, prev, next, nextnext, context): f'forbidden infinite value "{token.value}"', ) - if conf[ - 'forbid-scientific-notation' - ] and IS_SCIENTIFIC_NOTATION_PATTERN.match(val): + if conf['forbid-scientific-notation'] and IS_SCIENTIFIC_NOTATION_PATTERN.match(val): yield LintProblem( token.start_mark.line + 1, token.start_mark.column + 1, diff --git a/yamllint/rules/hyphens.py b/yamllint/rules/hyphens.py index 54a96bf1..7aa13a91 100644 --- a/yamllint/rules/hyphens.py +++ b/yamllint/rules/hyphens.py @@ -87,8 +87,12 @@ def check(conf, token, prev, next, nextnext, context): if isinstance(token, yaml.BlockEntryToken): - problem = spaces_after(token, prev, next, - max=conf['max-spaces-after'], - max_desc='too many spaces after hyphen') + problem = spaces_after( + token, + prev, + next, + max=conf['max-spaces-after'], + max_desc='too many spaces after hyphen', + ) if problem is not None: yield problem diff --git a/yamllint/rules/indentation.py b/yamllint/rules/indentation.py index bde6fa38..0f339182 100644 --- a/yamllint/rules/indentation.py +++ b/yamllint/rules/indentation.py @@ -206,12 +206,16 @@ ID = 'indentation' TYPE = 'token' -CONF = {'spaces': (int, 'consistent'), - 'indent-sequences': (bool, 'whatever', 'consistent'), - 'check-multi-line-strings': bool} -DEFAULT = {'spaces': 'consistent', - 'indent-sequences': True, - 'check-multi-line-strings': False} +CONF = { + 'spaces': (int, 'consistent'), + 'indent-sequences': (bool, 'whatever', 'consistent'), + 'check-multi-line-strings': bool, +} +DEFAULT = { + 'spaces': 'consistent', + 'indent-sequences': True, + 'check-multi-line-strings': False, +} ROOT, B_MAP, F_MAP, B_SEQ, F_SEQ, B_ENT, KEY, VAL = range(8) labels = ('ROOT', 'B_MAP', 'F_MAP', 'B_SEQ', 'F_SEQ', 'B_ENT', 'KEY', 'VAL') @@ -285,8 +289,10 @@ def detect_indent(base_indent): line_start = token.start_mark.pointer while True: - line_start = token.start_mark.buffer.find( - '\n', line_start, token.end_mark.pointer - 1) + 1 + line_start = ( + token.start_mark.buffer.find('\n', line_start, token.end_mark.pointer - 1) + + 1 + ) if line_start == 0: break line_no += 1 @@ -301,9 +307,11 @@ def detect_indent(base_indent): expected_indent = compute_expected_indent(indent) if indent != expected_indent: - yield LintProblem(line_no, indent + 1, - f'wrong indentation: expected {expected_indent}' - f'but found {indent}') + yield LintProblem( + line_no, + indent + 1, + f'wrong indentation: expected {expected_indent}' f'but found {indent}', + ) def _check(conf, token, prev, next, nextnext, context): @@ -316,11 +324,11 @@ def _check(conf, token, prev, next, nextnext, context): # Step 1: Lint is_visible = ( - not isinstance(token, (yaml.StreamStartToken, yaml.StreamEndToken)) and - not isinstance(token, yaml.BlockEndToken) and - not (isinstance(token, yaml.ScalarToken) and token.value == '')) - first_in_line = (is_visible and - token.start_mark.line + 1 > context['cur_line']) + not isinstance(token, (yaml.StreamStartToken, yaml.StreamEndToken)) + and not isinstance(token, yaml.BlockEndToken) + and not (isinstance(token, yaml.ScalarToken) and token.value == '') + ) + first_in_line = is_visible and token.start_mark.line + 1 > context['cur_line'] def detect_indent(base_indent, next): if not isinstance(context['spaces'], int): @@ -331,26 +339,28 @@ def detect_indent(base_indent, next): found_indentation = token.start_mark.column expected = context['stack'][-1].indent - if isinstance(token, (yaml.FlowMappingEndToken, - yaml.FlowSequenceEndToken)): + if isinstance(token, (yaml.FlowMappingEndToken, yaml.FlowSequenceEndToken)): expected = context['stack'][-1].line_indent - elif (context['stack'][-1].type == KEY and - context['stack'][-1].explicit_key and - not isinstance(token, yaml.ValueToken)): + elif ( + context['stack'][-1].type == KEY + and context['stack'][-1].explicit_key + and not isinstance(token, yaml.ValueToken) + ): expected = detect_indent(expected, token) if found_indentation != expected: if expected < 0: - message = f'wrong indentation: expected at least ' \ - f'{found_indentation + 1}' + message = ( + f'wrong indentation: expected at least ' f'{found_indentation + 1}' + ) else: - message = f'wrong indentation: expected {expected} but ' \ - f'found {found_indentation}' - yield LintProblem(token.start_mark.line + 1, - found_indentation + 1, message) + message = ( + f'wrong indentation: expected {expected} but ' + f'found {found_indentation}' + ) + yield LintProblem(token.start_mark.line + 1, found_indentation + 1, message) - if (isinstance(token, yaml.ScalarToken) and - conf['check-multi-line-strings']): + if isinstance(token, yaml.ScalarToken) and conf['check-multi-line-strings']: yield from check_scalar_indentation(conf, token, context) # Step 2.a: @@ -388,8 +398,9 @@ def detect_indent(base_indent, next): # } indent = detect_indent(context['cur_line_indent'], next) - context['stack'].append(Parent(F_MAP, indent, - line_indent=context['cur_line_indent'])) + context['stack'].append( + Parent(F_MAP, indent, line_indent=context['cur_line_indent']) + ) elif isinstance(token, yaml.BlockSequenceStartToken): # - - a @@ -401,9 +412,12 @@ def detect_indent(base_indent, next): context['stack'].append(Parent(B_SEQ, indent)) - elif (isinstance(token, yaml.BlockEntryToken) and - # in case of an empty entry - not isinstance(next, (yaml.BlockEntryToken, yaml.BlockEndToken))): + elif ( + isinstance(token, yaml.BlockEntryToken) + and + # in case of an empty entry + not isinstance(next, (yaml.BlockEntryToken, yaml.BlockEndToken)) + ): # It looks like pyyaml doesn't issue BlockSequenceStartTokens when the # list is not indented. We need to compensate that. if context['stack'][-1].type != B_SEQ: @@ -438,8 +452,9 @@ def detect_indent(base_indent, next): # ] indent = detect_indent(context['cur_line_indent'], next) - context['stack'].append(Parent(F_SEQ, indent, - line_indent=context['cur_line_indent'])) + context['stack'].append( + Parent(F_SEQ, indent, line_indent=context['cur_line_indent']) + ) elif isinstance(token, yaml.KeyToken): indent = context['stack'][-1].indent @@ -458,15 +473,22 @@ def detect_indent(base_indent, next): # key: !!tag # value if isinstance(next, (yaml.AnchorToken, yaml.TagToken)): - if (next.start_mark.line == prev.start_mark.line and - next.start_mark.line < nextnext.start_mark.line): + if ( + next.start_mark.line == prev.start_mark.line + and next.start_mark.line < nextnext.start_mark.line + ): next = nextnext # Only if value is not empty - if not isinstance(next, (yaml.BlockEndToken, - yaml.FlowMappingEndToken, - yaml.FlowSequenceEndToken, - yaml.KeyToken)): + if not isinstance( + next, + ( + yaml.BlockEndToken, + yaml.FlowMappingEndToken, + yaml.FlowSequenceEndToken, + yaml.KeyToken, + ), + ): if context['stack'][-1].explicit_key: # ? k # : value @@ -478,8 +500,7 @@ def detect_indent(base_indent, next): elif next.start_mark.line == prev.start_mark.line: # k: value indent = next.start_mark.column - elif isinstance(next, (yaml.BlockSequenceStartToken, - yaml.BlockEntryToken)): + elif isinstance(next, (yaml.BlockSequenceStartToken, yaml.BlockEntryToken)): # NOTE: We add BlockEntryToken in the test above because # sometimes BlockSequenceStartToken are not issued. Try # yaml.scan()ning this: @@ -488,9 +509,10 @@ def detect_indent(base_indent, next): if context['indent-sequences'] is False: indent = context['stack'][-1].indent elif context['indent-sequences'] is True: - if (context['spaces'] == 'consistent' and - next.start_mark.column - - context['stack'][-1].indent == 0): + if ( + context['spaces'] == 'consistent' + and next.start_mark.column - context['stack'][-1].indent == 0 + ): # In this case, the block sequence item is not indented # (while it should be), but we don't know yet the # indentation it should have (because `spaces` is @@ -499,8 +521,7 @@ def detect_indent(base_indent, next): # So we choose an unknown value (-1). indent = -1 else: - indent = detect_indent(context['stack'][-1].indent, - next) + indent = detect_indent(context['stack'][-1].indent, next) else: # 'whatever' or 'consistent' if next.start_mark.column == context['stack'][-1].indent: # key: @@ -515,8 +536,7 @@ def detect_indent(base_indent, next): # key: # - e1 # - e2 - indent = detect_indent(context['stack'][-1].indent, - next) + indent = detect_indent(context['stack'][-1].indent, next) else: # k: # value @@ -526,49 +546,64 @@ def detect_indent(base_indent, next): consumed_current_token = False while True: - if (context['stack'][-1].type == F_SEQ and - isinstance(token, yaml.FlowSequenceEndToken) and - not consumed_current_token): + if ( + context['stack'][-1].type == F_SEQ + and isinstance(token, yaml.FlowSequenceEndToken) + and not consumed_current_token + ): context['stack'].pop() consumed_current_token = True - elif (context['stack'][-1].type == F_MAP and - isinstance(token, yaml.FlowMappingEndToken) and - not consumed_current_token): + elif ( + context['stack'][-1].type == F_MAP + and isinstance(token, yaml.FlowMappingEndToken) + and not consumed_current_token + ): context['stack'].pop() consumed_current_token = True - elif (context['stack'][-1].type in (B_MAP, B_SEQ) and - isinstance(token, yaml.BlockEndToken) and - not context['stack'][-1].implicit_block_seq and - not consumed_current_token): + elif ( + context['stack'][-1].type in (B_MAP, B_SEQ) + and isinstance(token, yaml.BlockEndToken) + and not context['stack'][-1].implicit_block_seq + and not consumed_current_token + ): context['stack'].pop() consumed_current_token = True - elif (context['stack'][-1].type == B_ENT and - not isinstance(token, yaml.BlockEntryToken) and - context['stack'][-2].implicit_block_seq and - not isinstance(token, (yaml.AnchorToken, yaml.TagToken)) and - not isinstance(next, yaml.BlockEntryToken)): + elif ( + context['stack'][-1].type == B_ENT + and not isinstance(token, yaml.BlockEntryToken) + and context['stack'][-2].implicit_block_seq + and not isinstance(token, (yaml.AnchorToken, yaml.TagToken)) + and not isinstance(next, yaml.BlockEntryToken) + ): context['stack'].pop() context['stack'].pop() - elif (context['stack'][-1].type == B_ENT and - isinstance(next, (yaml.BlockEntryToken, yaml.BlockEndToken))): + elif context['stack'][-1].type == B_ENT and isinstance( + next, (yaml.BlockEntryToken, yaml.BlockEndToken) + ): context['stack'].pop() - elif (context['stack'][-1].type == VAL and - not isinstance(token, yaml.ValueToken) and - not isinstance(token, (yaml.AnchorToken, yaml.TagToken))): + elif ( + context['stack'][-1].type == VAL + and not isinstance(token, yaml.ValueToken) + and not isinstance(token, (yaml.AnchorToken, yaml.TagToken)) + ): assert context['stack'][-2].type == KEY context['stack'].pop() context['stack'].pop() - elif (context['stack'][-1].type == KEY and - isinstance(next, (yaml.BlockEndToken, - yaml.FlowMappingEndToken, - yaml.FlowSequenceEndToken, - yaml.KeyToken))): + elif context['stack'][-1].type == KEY and isinstance( + next, + ( + yaml.BlockEndToken, + yaml.FlowMappingEndToken, + yaml.FlowSequenceEndToken, + yaml.KeyToken, + ), + ): # A key without a value: it's part of a set. Let's drop this key # and leave room for the next one. context['stack'].pop() @@ -581,6 +616,8 @@ def check(conf, token, prev, next, nextnext, context): try: yield from _check(conf, token, prev, next, nextnext, context) except AssertionError: - yield LintProblem(token.start_mark.line + 1, - token.start_mark.column + 1, - 'cannot infer indentation: unexpected token') + yield LintProblem( + token.start_mark.line + 1, + token.start_mark.column + 1, + 'cannot infer indentation: unexpected token', + ) diff --git a/yamllint/rules/key_duplicates.py b/yamllint/rules/key_duplicates.py index 638ac1e0..80e709ba 100644 --- a/yamllint/rules/key_duplicates.py +++ b/yamllint/rules/key_duplicates.py @@ -111,28 +111,29 @@ def check(conf, token, prev, next, nextnext, context): if 'stack' not in context: context['stack'] = [] - if isinstance(token, (yaml.BlockMappingStartToken, - yaml.FlowMappingStartToken)): + if isinstance(token, (yaml.BlockMappingStartToken, yaml.FlowMappingStartToken)): context['stack'].append(Parent(MAP)) - elif isinstance(token, (yaml.BlockSequenceStartToken, - yaml.FlowSequenceStartToken)): + elif isinstance(token, (yaml.BlockSequenceStartToken, yaml.FlowSequenceStartToken)): context['stack'].append(Parent(SEQ)) - elif isinstance(token, (yaml.BlockEndToken, - yaml.FlowMappingEndToken, - yaml.FlowSequenceEndToken)): + elif isinstance( + token, (yaml.BlockEndToken, yaml.FlowMappingEndToken, yaml.FlowSequenceEndToken) + ): if len(context['stack']) > 0: context['stack'].pop() - elif (isinstance(token, yaml.KeyToken) and - isinstance(next, yaml.ScalarToken)): + elif isinstance(token, yaml.KeyToken) and isinstance(next, yaml.ScalarToken): # This check is done because KeyTokens can be found inside flow # sequences... strange, but allowed. if len(context['stack']) > 0 and context['stack'][-1].type == MAP: - if (next.value in context['stack'][-1].keys and - # `<<` is "merge key", see http://yaml.org/type/merge.html - (next.value != '<<' or - conf['forbid-duplicated-merge-keys'])): + if ( + next.value in context['stack'][-1].keys + and + # `<<` is "merge key", see http://yaml.org/type/merge.html + (next.value != '<<' or conf['forbid-duplicated-merge-keys']) + ): yield LintProblem( - next.start_mark.line + 1, next.start_mark.column + 1, - f'duplication of key "{next.value}" in mapping') + next.start_mark.line + 1, + next.start_mark.column + 1, + f'duplication of key "{next.value}" in mapping', + ) else: context['stack'][-1].keys.append(next.value) diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index ec0716d9..49330ace 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -102,25 +102,23 @@ def check(conf, token, prev, next, nextnext, context): if 'stack' not in context: context['stack'] = [] - if isinstance(token, (yaml.BlockMappingStartToken, - yaml.FlowMappingStartToken)): + if isinstance(token, (yaml.BlockMappingStartToken, yaml.FlowMappingStartToken)): context['stack'].append(Parent(MAP)) - elif isinstance(token, (yaml.BlockSequenceStartToken, - yaml.FlowSequenceStartToken)): + elif isinstance(token, (yaml.BlockSequenceStartToken, yaml.FlowSequenceStartToken)): context['stack'].append(Parent(SEQ)) - elif isinstance(token, (yaml.BlockEndToken, - yaml.FlowMappingEndToken, - yaml.FlowSequenceEndToken)): + elif isinstance( + token, (yaml.BlockEndToken, yaml.FlowMappingEndToken, yaml.FlowSequenceEndToken) + ): context['stack'].pop() - elif (isinstance(token, yaml.KeyToken) and - isinstance(next, yaml.ScalarToken)): + elif isinstance(token, yaml.KeyToken) and isinstance(next, yaml.ScalarToken): # This check is done because KeyTokens can be found inside flow # sequences... strange, but allowed. if len(context['stack']) > 0 and context['stack'][-1].type == MAP: - if any(strcoll(next.value, key) < 0 - for key in context['stack'][-1].keys): + if any(strcoll(next.value, key) < 0 for key in context['stack'][-1].keys): yield LintProblem( - next.start_mark.line + 1, next.start_mark.column + 1, - f'wrong ordering of key "{next.value}" in mapping') + next.start_mark.line + 1, + next.start_mark.column + 1, + f'wrong ordering of key "{next.value}" in mapping', + ) else: context['stack'][-1].keys.append(next.value) diff --git a/yamllint/rules/line_length.py b/yamllint/rules/line_length.py index 8214d74e..16bb94fe 100644 --- a/yamllint/rules/line_length.py +++ b/yamllint/rules/line_length.py @@ -103,12 +103,16 @@ ID = 'line-length' TYPE = 'line' -CONF = {'max': int, - 'allow-non-breakable-words': bool, - 'allow-non-breakable-inline-mappings': bool} -DEFAULT = {'max': 80, - 'allow-non-breakable-words': True, - 'allow-non-breakable-inline-mappings': False} +CONF = { + 'max': int, + 'allow-non-breakable-words': bool, + 'allow-non-breakable-inline-mappings': bool, +} +DEFAULT = { + 'max': 80, + 'allow-non-breakable-words': True, + 'allow-non-breakable-inline-mappings': False, +} def check_inline_mapping(line): @@ -120,8 +124,7 @@ def check_inline_mapping(line): if isinstance(loader.get_token(), yaml.ValueToken): t = loader.get_token() if isinstance(t, yaml.ScalarToken): - return ( - ' ' not in line.content[t.start_mark.column:]) + return ' ' not in line.content[t.start_mark.column :] except yaml.scanner.ScannerError: pass @@ -130,8 +133,7 @@ def check_inline_mapping(line): def check(conf, line): if line.end - line.start > conf['max']: - conf['allow-non-breakable-words'] |= \ - conf['allow-non-breakable-inline-mappings'] + conf['allow-non-breakable-words'] |= conf['allow-non-breakable-inline-mappings'] if conf['allow-non-breakable-words']: start = line.start while start < line.end and line.buffer[start] == ' ': @@ -148,10 +150,13 @@ def check(conf, line): if line.buffer.find(' ', start, line.end) == -1: return - if (conf['allow-non-breakable-inline-mappings'] and - check_inline_mapping(line)): + if conf['allow-non-breakable-inline-mappings'] and check_inline_mapping( + line + ): return - yield LintProblem(line.line_no, conf['max'] + 1, - 'line too long (%d > %d characters)' % - (line.end - line.start, conf['max'])) + yield LintProblem( + line.line_no, + conf['max'] + 1, + 'line too long (%d > %d characters)' % (line.end - line.start, conf['max']), + ) diff --git a/yamllint/rules/new_line_at_end_of_file.py b/yamllint/rules/new_line_at_end_of_file.py index f49edb95..def46736 100644 --- a/yamllint/rules/new_line_at_end_of_file.py +++ b/yamllint/rules/new_line_at_end_of_file.py @@ -31,5 +31,8 @@ def check(conf, line): if line.end == len(line.buffer) and line.end > line.start: - yield LintProblem(line.line_no, line.end - line.start + 1, - 'no new line character at the end of file') + yield LintProblem( + line.line_no, + line.end - line.start + 1, + 'no new line character at the end of file', + ) diff --git a/yamllint/rules/new_lines.py b/yamllint/rules/new_lines.py index 2ee5512a..8d5e8334 100644 --- a/yamllint/rules/new_lines.py +++ b/yamllint/rules/new_lines.py @@ -52,7 +52,8 @@ def check(conf, line): newline_char = '\r\n' if line.start == 0 and len(line.buffer) > line.end: - if line.buffer[line.end:line.end + len(newline_char)] != newline_char: - c = repr(newline_char).strip('\'') - yield LintProblem(1, line.end - line.start + 1, - f'wrong new line character: expected {c}') + if line.buffer[line.end : line.end + len(newline_char)] != newline_char: + c = repr(newline_char).strip("'") + yield LintProblem( + 1, line.end - line.start + 1, f'wrong new line character: expected {c}' + ) diff --git a/yamllint/rules/octal_values.py b/yamllint/rules/octal_values.py index e94e4bff..01872ef7 100644 --- a/yamllint/rules/octal_values.py +++ b/yamllint/rules/octal_values.py @@ -78,10 +78,8 @@ ID = 'octal-values' TYPE = 'token' -CONF = {'forbid-implicit-octal': bool, - 'forbid-explicit-octal': bool} -DEFAULT = {'forbid-implicit-octal': True, - 'forbid-explicit-octal': True} +CONF = {'forbid-implicit-octal': bool, 'forbid-explicit-octal': bool} +DEFAULT = {'forbid-implicit-octal': True, 'forbid-explicit-octal': True} IS_OCTAL_NUMBER_PATTERN = re.compile(r'^[0-7]+$') @@ -94,18 +92,29 @@ def check(conf, token, prev, next, nextnext, context): if isinstance(token, yaml.tokens.ScalarToken): if not token.style: val = token.value - if (val.isdigit() and len(val) > 1 and val[0] == '0' and - IS_OCTAL_NUMBER_PATTERN.match(val[1:])): + if ( + val.isdigit() + and len(val) > 1 + and val[0] == '0' + and IS_OCTAL_NUMBER_PATTERN.match(val[1:]) + ): yield LintProblem( - token.start_mark.line + 1, token.end_mark.column + 1, - f'forbidden implicit octal value "{token.value}"') + token.start_mark.line + 1, + token.end_mark.column + 1, + f'forbidden implicit octal value "{token.value}"', + ) if conf['forbid-explicit-octal']: if isinstance(token, yaml.tokens.ScalarToken): if not token.style: val = token.value - if (len(val) > 2 and val[:2] == '0o' and - IS_OCTAL_NUMBER_PATTERN.match(val[2:])): + if ( + len(val) > 2 + and val[:2] == '0o' + and IS_OCTAL_NUMBER_PATTERN.match(val[2:]) + ): yield LintProblem( - token.start_mark.line + 1, token.end_mark.column + 1, - f'forbidden explicit octal value "{token.value}"') + token.start_mark.line + 1, + token.end_mark.column + 1, + f'forbidden explicit octal value "{token.value}"', + ) diff --git a/yamllint/rules/quoted_strings.py b/yamllint/rules/quoted_strings.py index 5bfbd7a7..d5b1079c 100644 --- a/yamllint/rules/quoted_strings.py +++ b/yamllint/rules/quoted_strings.py @@ -161,18 +161,22 @@ ID = 'quoted-strings' TYPE = 'token' -CONF = {'quote-type': ('any', 'single', 'double'), - 'required': (True, False, 'only-when-needed'), - 'extra-required': [str], - 'extra-allowed': [str], - 'allow-quoted-quotes': bool, - 'check-keys': bool} -DEFAULT = {'quote-type': 'any', - 'required': True, - 'extra-required': [], - 'extra-allowed': [], - 'allow-quoted-quotes': False, - 'check-keys': False} +CONF = { + 'quote-type': ('any', 'single', 'double'), + 'required': (True, False, 'only-when-needed'), + 'extra-required': [str], + 'extra-allowed': [str], + 'allow-quoted-quotes': bool, + 'check-keys': bool, +} +DEFAULT = { + 'quote-type': 'any', + 'required': True, + 'extra-required': [], + 'extra-allowed': [], + 'allow-quoted-quotes': False, + 'check-keys': False, +} def VALIDATE(conf): @@ -189,19 +193,25 @@ def VALIDATE(conf): # https://stackoverflow.com/a/36514274 yaml.resolver.Resolver.add_implicit_resolver( 'tag:yaml.org,2002:int', - re.compile(r'''^(?:[-+]?0b[0-1_]+ + re.compile( + r"""^(?:[-+]?0b[0-1_]+ |[-+]?0o?[0-7_]+ |[-+]?0[0-7_]+ |[-+]?(?:0|[1-9][0-9_]*) |[-+]?0x[0-9a-fA-F_]+ - |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.VERBOSE), - list('-+0123456789')) + |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$""", + re.VERBOSE, + ), + list('-+0123456789'), +) def _quote_match(quote_type, token_style): - return ((quote_type == 'any') or - (quote_type == 'single' and token_style == "'") or - (quote_type == 'double' and token_style == '"')) + return ( + (quote_type == 'any') + or (quote_type == 'single' and token_style == "'") + or (quote_type == 'double' and token_style == '"') + ) def _quotes_are_needed(string, is_inside_a_flow): @@ -216,8 +226,12 @@ def _quotes_are_needed(string, is_inside_a_flow): loader.get_token() try: a, b = loader.get_token(), loader.get_token() - if (isinstance(a, yaml.ScalarToken) and a.style is None and - isinstance(b, yaml.BlockEndToken) and a.value == string): + if ( + isinstance(a, yaml.ScalarToken) + and a.style is None + and isinstance(b, yaml.BlockEndToken) + and a.value == string + ): return False return True except yaml.scanner.ScannerError: @@ -225,27 +239,35 @@ def _quotes_are_needed(string, is_inside_a_flow): def _has_quoted_quotes(token): - return ((not token.plain) and - ((token.style == "'" and '"' in token.value) or - (token.style == '"' and "'" in token.value))) + return (not token.plain) and ( + (token.style == "'" and '"' in token.value) + or (token.style == '"' and "'" in token.value) + ) def check(conf, token, prev, next, nextnext, context): if 'flow_nest_count' not in context: context['flow_nest_count'] = 0 - if isinstance(token, (yaml.FlowMappingStartToken, - yaml.FlowSequenceStartToken)): + if isinstance(token, (yaml.FlowMappingStartToken, yaml.FlowSequenceStartToken)): context['flow_nest_count'] += 1 - elif isinstance(token, (yaml.FlowMappingEndToken, - yaml.FlowSequenceEndToken)): + elif isinstance(token, (yaml.FlowMappingEndToken, yaml.FlowSequenceEndToken)): context['flow_nest_count'] -= 1 - if not (isinstance(token, yaml.tokens.ScalarToken) and - isinstance(prev, (yaml.BlockEntryToken, yaml.FlowEntryToken, - yaml.FlowSequenceStartToken, yaml.TagToken, - yaml.ValueToken, yaml.KeyToken))): - + if not ( + isinstance(token, yaml.tokens.ScalarToken) + and isinstance( + prev, + ( + yaml.BlockEntryToken, + yaml.FlowEntryToken, + yaml.FlowSequenceStartToken, + yaml.TagToken, + yaml.ValueToken, + yaml.KeyToken, + ), + ) + ): return node = 'key' if isinstance(prev, yaml.KeyToken) else 'value' @@ -253,8 +275,7 @@ def check(conf, token, prev, next, nextnext, context): return # Ignore explicit types, e.g. !!str testtest or !!int 42 - if (prev and isinstance(prev, yaml.tokens.TagToken) and - prev.value[0] == '!!'): + if prev and isinstance(prev, yaml.tokens.TagToken) and prev.value[0] == '!!': return # Ignore numbers, booleans, etc. @@ -264,63 +285,69 @@ def check(conf, token, prev, next, nextnext, context): return # Ignore multi-line strings - if not token.plain and token.style in ("|", ">"): + if not token.plain and token.style in ('|', '>'): return quote_type = conf['quote-type'] msg = None if conf['required'] is True: - # Quotes are mandatory and need to match config - if (token.style is None or - not (_quote_match(quote_type, token.style) or - (conf['allow-quoted-quotes'] and _has_quoted_quotes(token)))): - msg = f"string {node} is not quoted with {quote_type} quotes" + if token.style is None or not ( + _quote_match(quote_type, token.style) + or (conf['allow-quoted-quotes'] and _has_quoted_quotes(token)) + ): + msg = f'string {node} is not quoted with {quote_type} quotes' elif conf['required'] is False: - # Quotes are not mandatory but when used need to match config - if (token.style and - not _quote_match(quote_type, token.style) and - not (conf['allow-quoted-quotes'] and - _has_quoted_quotes(token))): - msg = f"string {node} is not quoted with {quote_type} quotes" + if ( + token.style + and not _quote_match(quote_type, token.style) + and not (conf['allow-quoted-quotes'] and _has_quoted_quotes(token)) + ): + msg = f'string {node} is not quoted with {quote_type} quotes' elif not token.style: - is_extra_required = any(re.search(r, token.value) - for r in conf['extra-required']) + is_extra_required = any( + re.search(r, token.value) for r in conf['extra-required'] + ) if is_extra_required: - msg = f"string {node} is not quoted" + msg = f'string {node} is not quoted' elif conf['required'] == 'only-when-needed': - # Quotes are not strictly needed here - if (token.style and tag == DEFAULT_SCALAR_TAG and token.value and - not _quotes_are_needed(token.value, - context['flow_nest_count'] > 0)): - is_extra_required = any(re.search(r, token.value) - for r in conf['extra-required']) - is_extra_allowed = any(re.search(r, token.value) - for r in conf['extra-allowed']) + if ( + token.style + and tag == DEFAULT_SCALAR_TAG + and token.value + and not _quotes_are_needed(token.value, context['flow_nest_count'] > 0) + ): + is_extra_required = any( + re.search(r, token.value) for r in conf['extra-required'] + ) + is_extra_allowed = any( + re.search(r, token.value) for r in conf['extra-allowed'] + ) if not (is_extra_required or is_extra_allowed): - msg = f"string {node} is redundantly quoted with " \ - f"{quote_type} quotes" + msg = ( + f'string {node} is redundantly quoted with ' f'{quote_type} quotes' + ) # But when used need to match config - elif (token.style and - not _quote_match(quote_type, token.style) and - not (conf['allow-quoted-quotes'] and _has_quoted_quotes(token))): - msg = f"string {node} is not quoted with {quote_type} quotes" + elif ( + token.style + and not _quote_match(quote_type, token.style) + and not (conf['allow-quoted-quotes'] and _has_quoted_quotes(token)) + ): + msg = f'string {node} is not quoted with {quote_type} quotes' elif not token.style: is_extra_required = len(conf['extra-required']) and any( - re.search(r, token.value) for r in conf['extra-required']) + re.search(r, token.value) for r in conf['extra-required'] + ) if is_extra_required: - msg = f"string {node} is not quoted" + msg = f'string {node} is not quoted' if msg is not None: - yield LintProblem( - token.start_mark.line + 1, - token.start_mark.column + 1, - msg) + yield LintProblem(token.start_mark.line + 1, token.start_mark.column + 1, msg) diff --git a/yamllint/rules/trailing_spaces.py b/yamllint/rules/trailing_spaces.py index b5455f32..6ac0cbb7 100644 --- a/yamllint/rules/trailing_spaces.py +++ b/yamllint/rules/trailing_spaces.py @@ -56,5 +56,4 @@ def check(conf, line): pos -= 1 if pos != line.end and line.buffer[pos] in ' \t': - yield LintProblem(line.line_no, pos - line.start + 1, - 'trailing spaces') + yield LintProblem(line.line_no, pos - line.start + 1, 'trailing spaces') diff --git a/yamllint/rules/truthy.py b/yamllint/rules/truthy.py index 4b7179ab..8f590e57 100644 --- a/yamllint/rules/truthy.py +++ b/yamllint/rules/truthy.py @@ -125,12 +125,26 @@ from yamllint.linter import LintProblem -TRUTHY = ['YES', 'Yes', 'yes', - 'NO', 'No', 'no', - 'TRUE', 'True', 'true', - 'FALSE', 'False', 'false', - 'ON', 'On', 'on', - 'OFF', 'Off', 'off'] +TRUTHY = [ + 'YES', + 'Yes', + 'yes', + 'NO', + 'No', + 'no', + 'TRUE', + 'True', + 'true', + 'FALSE', + 'False', + 'false', + 'ON', + 'On', + 'on', + 'OFF', + 'Off', + 'off', +] ID = 'truthy' @@ -143,14 +157,22 @@ def check(conf, token, prev, next, nextnext, context): if prev and isinstance(prev, yaml.tokens.TagToken): return - if (not conf['check-keys'] and isinstance(prev, yaml.tokens.KeyToken) and - isinstance(token, yaml.tokens.ScalarToken)): + if ( + not conf['check-keys'] + and isinstance(prev, yaml.tokens.KeyToken) + and isinstance(token, yaml.tokens.ScalarToken) + ): return if isinstance(token, yaml.tokens.ScalarToken): - if (token.value in (set(TRUTHY) - set(conf['allowed-values'])) and - token.style is None): - yield LintProblem(token.start_mark.line + 1, - token.start_mark.column + 1, - "truthy value should be one of [" + - ", ".join(sorted(conf['allowed-values'])) + "]") + if ( + token.value in (set(TRUTHY) - set(conf['allowed-values'])) + and token.style is None + ): + yield LintProblem( + token.start_mark.line + 1, + token.start_mark.column + 1, + 'truthy value should be one of [' + + ', '.join(sorted(conf['allowed-values'])) + + ']', + )