test_formatters.py (3853B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 import json 6 from textwrap import dedent 7 8 import attr 9 import mozpack.path as mozpath 10 import mozunit 11 import pytest 12 13 from mozlint import formatters 14 from mozlint.result import Issue, ResultSummary 15 16 NORMALISED_PATHS = { 17 "abc": mozpath.normpath("a/b/c.txt"), 18 "def": mozpath.normpath("d/e/f.txt"), 19 "root": mozpath.abspath("/fake/root"), 20 } 21 22 EXPECTED = { 23 "compact": { 24 "kwargs": {}, 25 "format": """ 26 /fake/root/a/b/c.txt: line 1, Error - oh no foo (foo) 27 /fake/root/a/b/c.txt: line 4, col 10, Error - oh no baz (baz) 28 /fake/root/a/b/c.txt: line 5, Error - oh no foo-diff (foo-diff) 29 /fake/root/d/e/f.txt: line 4, col 2, Warning - oh no bar (bar-not-allowed) 30 31 4 problems 32 """.strip(), 33 }, 34 "stylish": { 35 "kwargs": {"disable_colors": True}, 36 "format": """ 37 /fake/root/a/b/c.txt 38 1 error oh no foo (foo) 39 4:10 error oh no baz (baz) 40 | 41 4 | if baz: 42 | ^^^ 43 5 error oh no foo-diff (foo-diff) 44 diff 1 45 - hello 46 + hello2 47 48 /fake/root/d/e/f.txt 49 4:2 warning oh no bar bar-not-allowed (bar) 50 51 \u2716 4 problems (3 errors, 1 warning, 0 fixed) 52 """.strip(), 53 }, 54 "treeherder": { 55 "kwargs": {}, 56 "format": """ 57 TEST-UNEXPECTED-ERROR | /fake/root/a/b/c.txt:1 | oh no foo (foo) 58 TEST-UNEXPECTED-ERROR | /fake/root/a/b/c.txt:4:10 | oh no baz (baz) 59 TEST-UNEXPECTED-ERROR | /fake/root/a/b/c.txt:5 | oh no foo-diff (foo-diff) 60 TEST-UNEXPECTED-WARNING | /fake/root/d/e/f.txt:4:2 | oh no bar (bar-not-allowed) 61 """.strip(), 62 }, 63 "unix": { 64 "kwargs": {}, 65 "format": """ 66 {abc}:1: foo error: oh no foo 67 {abc}:4:10: baz error: oh no baz 68 {abc}:5: foo-diff error: oh no foo-diff 69 {def}:4:2: bar-not-allowed warning: oh no bar 70 """.format(**NORMALISED_PATHS).strip(), 71 }, 72 "summary": { 73 "kwargs": {}, 74 "format": """ 75 {root}/a: 3 errors 76 {root}/d: 0 errors, 1 warning 77 """.format(**NORMALISED_PATHS).strip(), 78 }, 79 } 80 81 82 @pytest.fixture 83 def result(scope="module"): 84 result = ResultSummary("/fake/root") 85 containers = ( 86 Issue(linter="foo", path="a/b/c.txt", message="oh no foo", lineno=1), 87 Issue( 88 linter="bar", 89 path="d/e/f.txt", 90 message="oh no bar", 91 hint="try baz instead", 92 level="warning", 93 lineno="4", 94 column="2", 95 rule="bar-not-allowed", 96 ), 97 Issue( 98 linter="baz", 99 path="a/b/c.txt", 100 message="oh no baz", 101 lineno=4, 102 column=10, 103 source=dedent( 104 """ 105 | 106 4 | if baz: 107 | ^^^ 108 """ 109 ).lstrip("\n"), 110 ), 111 Issue( 112 linter="foo-diff", 113 path="a/b/c.txt", 114 message="oh no foo-diff", 115 lineno=5, 116 diff="diff 1\n- hello\n+ hello2", 117 ), 118 ) 119 result = ResultSummary("/fake/root") 120 for c in containers: 121 result.issues[c.path].append(c) 122 return result 123 124 125 @pytest.mark.parametrize("name", EXPECTED.keys()) 126 def test_formatters(result, name): 127 opts = EXPECTED[name] 128 fmt = formatters.get(name, **opts["kwargs"]) 129 # encoding to str bypasses a UnicodeEncodeError in pytest 130 assert fmt(result) == opts["format"] 131 132 133 def test_json_formatter(result): 134 fmt = formatters.get("json") 135 formatted = json.loads(fmt(result)) 136 137 assert set(formatted.keys()) == set(result.issues.keys()) 138 139 attrs = attr.fields(Issue) 140 for errors in formatted.values(): 141 for err in errors: 142 assert all(a.name in err for a in attrs) 143 144 145 if __name__ == "__main__": 146 mozunit.main()