Bug 1302172 - [mozlint] Convert unittest tests to use pytest instead, r=maja_zf
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Fri, 09 Sep 2016 16:20:09 -0400
changeset 355191 8bce29dda76e4e5d09eb7d91ef4e335629d6861f
parent 355190 24cefbae2be9111f84604e18fbacfd2548ac26ed
child 355192 a6637618e917ae88cdfc547a276192ec40dd9f0f
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmaja_zf
bugs1302172
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1302172 - [mozlint] Convert unittest tests to use pytest instead, r=maja_zf MozReview-Commit-ID: D4bN62QbkKm
python/mozlint/test/conftest.py
python/mozlint/test/test_formatters.py
python/mozlint/test/test_parser.py
python/mozlint/test/test_roller.py
python/mozlint/test/test_types.py
new file mode 100644
--- /dev/null
+++ b/python/mozlint/test/conftest.py
@@ -0,0 +1,42 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+
+import pytest
+
+from mozlint import LintRoller
+
+
+here = os.path.abspath(os.path.dirname(__file__))
+
+
+@pytest.fixture
+def lint(request):
+    lintargs = getattr(request.module, 'lintargs', {})
+    return LintRoller(root=here, **lintargs)
+
+
+@pytest.fixture(scope='session')
+def filedir():
+    return os.path.join(here, 'files')
+
+
+@pytest.fixture(scope='module')
+def files(filedir, request):
+    suffix_filter = getattr(request.module, 'files', [''])
+    return [os.path.join(filedir, p) for p in os.listdir(filedir)
+            if any(p.endswith(suffix) for suffix in suffix_filter)]
+
+
+@pytest.fixture(scope='session')
+def lintdir():
+    return os.path.join(here, 'linters')
+
+
+@pytest.fixture(scope='module')
+def linters(lintdir, request):
+    suffix_filter = getattr(request.module, 'linters', ['.lint'])
+    return [os.path.join(lintdir, p) for p in os.listdir(lintdir)
+            if any(p.endswith(suffix) for suffix in suffix_filter)]
--- a/python/mozlint/test/test_formatters.py
+++ b/python/mozlint/test/test_formatters.py
@@ -1,94 +1,90 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import unicode_literals
 
 import json
-import os
+import sys
 from collections import defaultdict
-from unittest import TestCase
 
-from mozunit import main
+import pytest
 
 from mozlint import ResultContainer
 from mozlint import formatters
 
 
-here = os.path.abspath(os.path.dirname(__file__))
+@pytest.fixture
+def results(scope='module'):
+    containers = (
+        ResultContainer(
+            linter='foo',
+            path='a/b/c.txt',
+            message="oh no foo",
+            lineno=1,
+        ),
+        ResultContainer(
+            linter='bar',
+            path='d/e/f.txt',
+            message="oh no bar",
+            hint="try baz instead",
+            level='warning',
+            lineno=4,
+            column=2,
+            rule="bar-not-allowed",
+        ),
+        ResultContainer(
+            linter='baz',
+            path='a/b/c.txt',
+            message="oh no baz",
+            lineno=4,
+            source="if baz:",
+        ),
+    )
+    results = defaultdict(list)
+    for c in containers:
+        results[c.path].append(c)
+    return results
 
 
-class TestFormatters(TestCase):
-
-    def __init__(self, *args, **kwargs):
-        TestCase.__init__(self, *args, **kwargs)
-
-        containers = (
-            ResultContainer(
-                linter='foo',
-                path='a/b/c.txt',
-                message="oh no foo",
-                lineno=1,
-            ),
-            ResultContainer(
-                linter='bar',
-                path='d/e/f.txt',
-                message="oh no bar",
-                hint="try baz instead",
-                level='warning',
-                lineno=4,
-                column=2,
-                rule="bar-not-allowed",
-            ),
-            ResultContainer(
-                linter='baz',
-                path='a/b/c.txt',
-                message="oh no baz",
-                lineno=4,
-                source="if baz:",
-            ),
-        )
-
-        self.results = defaultdict(list)
-        for c in containers:
-            self.results[c.path].append(c)
-
-    def test_stylish_formatter(self):
-        expected = """
+def test_stylish_formatter(results):
+    expected = """
 a/b/c.txt
   1  error  oh no foo  (foo)
   4  error  oh no baz  (baz)
 
 d/e/f.txt
   4:2  warning  oh no bar  bar-not-allowed (bar)
 
 \u2716 3 problems (2 errors, 1 warning)
 """.strip()
 
-        fmt = formatters.get('stylish', disable_colors=True)
-        self.assertEqual(expected, fmt(self.results))
+    fmt = formatters.get('stylish', disable_colors=True)
+    assert expected == fmt(results)
 
-    def test_treeherder_formatter(self):
-        expected = """
+
+def test_treeherder_formatter(results):
+    expected = """
 TEST-UNEXPECTED-ERROR | a/b/c.txt:1 | oh no foo (foo)
 TEST-UNEXPECTED-ERROR | a/b/c.txt:4 | oh no baz (baz)
 TEST-UNEXPECTED-WARNING | d/e/f.txt:4:2 | oh no bar (bar-not-allowed)
 """.strip()
 
-        fmt = formatters.get('treeherder')
-        self.assertEqual(expected, fmt(self.results))
+    fmt = formatters.get('treeherder')
+    assert expected == fmt(results)
 
-    def test_json_formatter(self):
-        fmt = formatters.get('json')
-        formatted = json.loads(fmt(self.results))
 
-        self.assertEqual(set(formatted.keys()), set(self.results.keys()))
+def test_json_formatter(results):
+    fmt = formatters.get('json')
+    formatted = json.loads(fmt(results))
 
-        slots = ResultContainer.__slots__
-        for errors in formatted.values():
-            for err in errors:
-                self.assertTrue(all(s in err for s in slots))
+    assert set(formatted.keys()) == set(results.keys())
+
+    slots = ResultContainer.__slots__
+    for errors in formatted.values():
+        for err in errors:
+            assert all(s in err for s in slots)
 
 
 if __name__ == '__main__':
-    main()
+    sys.exit(pytest.main(['--verbose', __file__]))
--- a/python/mozlint/test/test_parser.py
+++ b/python/mozlint/test/test_parser.py
@@ -1,68 +1,55 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
-from unittest import TestCase
+import sys
 
-from mozunit import main
+import pytest
 
 from mozlint.parser import Parser
 from mozlint.errors import (
     LinterNotFound,
     LinterParseError,
 )
 
 
-here = os.path.abspath(os.path.dirname(__file__))
+@pytest.fixture(scope='module')
+def parse(lintdir):
+    parser = Parser()
+
+    def _parse(name):
+        path = os.path.join(lintdir, name)
+        return parser(path)
+    return _parse
 
 
-class TestParser(TestCase):
-
-    def __init__(self, *args, **kwargs):
-        TestCase.__init__(self, *args, **kwargs)
-
-        self._lintdir = os.path.join(here, 'linters')
-        self._parse = Parser()
-
-    def parse(self, name):
-        return self._parse(os.path.join(self._lintdir, name))
+def test_parse_valid_linter(parse):
+    lintobj = parse('string.lint')
+    assert isinstance(lintobj, dict)
+    assert 'name' in lintobj
+    assert 'description' in lintobj
+    assert 'type' in lintobj
+    assert 'payload' in lintobj
 
-    def test_parse_valid_linter(self):
-        linter = self.parse('string.lint')
-        self.assertIsInstance(linter, dict)
-        self.assertIn('name', linter)
-        self.assertIn('description', linter)
-        self.assertIn('type', linter)
-        self.assertIn('payload', linter)
-
-    def test_parse_invalid_type(self):
-        with self.assertRaises(LinterParseError):
-            self.parse('invalid_type.lint')
 
-    def test_parse_invalid_extension(self):
-        with self.assertRaises(LinterParseError):
-            self.parse('invalid_extension.lnt')
-
-    def test_parse_invalid_include_exclude(self):
-        with self.assertRaises(LinterParseError):
-            self.parse('invalid_include.lint')
-
-        with self.assertRaises(LinterParseError):
-            self.parse('invalid_exclude.lint')
+@pytest.mark.parametrize('linter', [
+    'invalid_type.lint',
+    'invalid_extension.lnt',
+    'invalid_include.lint',
+    'invalid_exclude.lint',
+    'missing_attrs.lint',
+    'missing_definition.lint',
+])
+def test_parse_invalid_linter(parse, linter):
+    with pytest.raises(LinterParseError):
+        parse(linter)
 
-    def test_parse_missing_attributes(self):
-        with self.assertRaises(LinterParseError):
-            self.parse('missing_attrs.lint')
 
-    def test_parse_missing_definition(self):
-        with self.assertRaises(LinterParseError):
-            self.parse('missing_definition.lint')
-
-    def test_parse_non_existent_linter(self):
-        with self.assertRaises(LinterNotFound):
-            self.parse('missing_file.lint')
+def test_parse_non_existent_linter(parse):
+    with pytest.raises(LinterNotFound):
+        parse('missing_file.lint')
 
 
 if __name__ == '__main__':
-    main()
+    sys.exit(pytest.main(['--verbose', __file__]))
--- a/python/mozlint/test/test_roller.py
+++ b/python/mozlint/test/test_roller.py
@@ -1,80 +1,70 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
 import sys
-from unittest import TestCase
 
-from mozunit import main
+import pytest
 
-from mozlint import LintRoller, ResultContainer
+from mozlint import ResultContainer
 from mozlint.errors import LintersNotConfigured, LintException
 
 
 here = os.path.abspath(os.path.dirname(__file__))
 
 
-class TestLintRoller(TestCase):
+linters = ('string.lint', 'regex.lint', 'external.lint')
 
-    def __init__(self, *args, **kwargs):
-        TestCase.__init__(self, *args, **kwargs)
 
-        self.filedir = os.path.join(here, 'files')
-        self.files = [os.path.join(self.filedir, f) for f in os.listdir(self.filedir)]
-        self.lintdir = os.path.join(here, 'linters')
+def test_roll_no_linters_configured(lint, files):
+    with pytest.raises(LintersNotConfigured):
+        lint.roll(files)
 
-        names = ('string.lint', 'regex.lint', 'external.lint')
-        self.linters = [os.path.join(self.lintdir, n) for n in names]
+
+def test_roll_successful(lint, linters, files):
+    lint.read(linters)
 
-    def setUp(self):
-        TestCase.setUp(self)
-        self.lint = LintRoller(root=here)
+    result = lint.roll(files)
+    assert len(result) == 1
 
-    def test_roll_no_linters_configured(self):
-        with self.assertRaises(LintersNotConfigured):
-            self.lint.roll(self.files)
+    path = result.keys()[0]
+    assert os.path.basename(path) == 'foobar.js'
 
-    def test_roll_successful(self):
-        self.lint.read(self.linters)
+    errors = result[path]
+    assert isinstance(errors, list)
+    assert len(errors) == 6
 
-        result = self.lint.roll(self.files)
-        self.assertEqual(len(result), 1)
-
-        path = result.keys()[0]
-        self.assertEqual(os.path.basename(path), 'foobar.js')
+    container = errors[0]
+    assert isinstance(container, ResultContainer)
+    assert container.rule == 'no-foobar'
 
-        errors = result[path]
-        self.assertIsInstance(errors, list)
-        self.assertEqual(len(errors), 6)
+
+def test_roll_catch_exception(lint, lintdir, files):
+    lint.read(os.path.join(lintdir, 'raises.lint'))
 
-        container = errors[0]
-        self.assertIsInstance(container, ResultContainer)
-        self.assertEqual(container.rule, 'no-foobar')
+    # suppress printed traceback from test output
+    old_stderr = sys.stderr
+    sys.stderr = open(os.devnull, 'w')
+    with pytest.raises(LintException):
+        lint.roll(files)
+    sys.stderr = old_stderr
 
-    def test_roll_catch_exception(self):
-        self.lint.read(os.path.join(self.lintdir, 'raises.lint'))
 
-        # suppress printed traceback from test output
-        old_stderr = sys.stderr
-        sys.stderr = open(os.devnull, 'w')
-        with self.assertRaises(LintException):
-            self.lint.roll(self.files)
-        sys.stderr = old_stderr
+def test_roll_with_excluded_path(lint, linters, files):
+    lint.lintargs.update({'exclude': ['**/foobar.js']})
 
-    def test_roll_with_excluded_path(self):
-        self.lint.lintargs.update({'exclude': ['**/foobar.js']})
+    lint.read(linters)
+    result = lint.roll(files)
 
-        self.lint.read(self.linters)
-        result = self.lint.roll(self.files)
+    assert len(result) == 0
 
-        self.assertEqual(len(result), 0)
 
-    def test_roll_with_invalid_extension(self):
-        self.lint.read(os.path.join(self.lintdir, 'external.lint'))
-        result = self.lint.roll(os.path.join(self.filedir, 'foobar.py'))
-        self.assertEqual(len(result), 0)
+def test_roll_with_invalid_extension(lint, lintdir, filedir):
+    lint.read(os.path.join(lintdir, 'external.lint'))
+    result = lint.roll(os.path.join(filedir, 'foobar.py'))
+    assert len(result) == 0
 
 
 if __name__ == '__main__':
-    main()
+    sys.exit(pytest.main(['--verbose', __file__]))
--- a/python/mozlint/test/test_types.py
+++ b/python/mozlint/test/test_types.py
@@ -1,78 +1,50 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
-from unittest import TestCase
+import sys
 
-from mozunit import main
+import pytest
 
-from mozlint import LintRoller
 from mozlint.result import ResultContainer
 
 
-here = os.path.abspath(os.path.dirname(__file__))
+@pytest.fixture
+def path(filedir):
+    def _path(name):
+        return os.path.join(filedir, name)
+    return _path
+
+
+@pytest.fixture(params=['string.lint', 'regex.lint', 'external.lint'])
+def linter(lintdir, request):
+    return os.path.join(lintdir, request.param)
 
 
-class TestLinterTypes(TestCase):
-
-    def __init__(self, *args, **kwargs):
-        TestCase.__init__(self, *args, **kwargs)
-
-        self.lintdir = os.path.join(here, 'linters')
-        self.filedir = os.path.join(here, 'files')
-        self.files = [os.path.join(self.filedir, f) for f in os.listdir(self.filedir)]
-
-    def setUp(self):
-        TestCase.setUp(self)
-        self.lint = LintRoller(root=here)
+def test_linter_types(lint, linter, files, path):
+    lint.read(linter)
+    result = lint.roll(files)
+    assert isinstance(result, dict)
+    assert path('foobar.js') in result
+    assert path('no_foobar.js') not in result
 
-    def path(self, name):
-        return os.path.join(self.filedir, name)
-
-    def test_string_linter(self):
-        self.lint.read(os.path.join(self.lintdir, 'string.lint'))
-        result = self.lint.roll(self.files)
-        self.assertIsInstance(result, dict)
-
-        self.assertIn(self.path('foobar.js'), result.keys())
-        self.assertNotIn(self.path('no_foobar.js'), result.keys())
-
-        result = result[self.path('foobar.js')][0]
-        self.assertIsInstance(result, ResultContainer)
-        self.assertEqual(result.linter, 'StringLinter')
+    result = result[path('foobar.js')][0]
+    assert isinstance(result, ResultContainer)
 
-    def test_regex_linter(self):
-        self.lint.read(os.path.join(self.lintdir, 'regex.lint'))
-        result = self.lint.roll(self.files)
-        self.assertIsInstance(result, dict)
-        self.assertIn(self.path('foobar.js'), result.keys())
-        self.assertNotIn(self.path('no_foobar.js'), result.keys())
+    name = os.path.basename(linter).split('.')[0]
+    assert result.linter.lower().startswith(name)
 
-        result = result[self.path('foobar.js')][0]
-        self.assertIsInstance(result, ResultContainer)
-        self.assertEqual(result.linter, 'RegexLinter')
 
-    def test_external_linter(self):
-        self.lint.read(os.path.join(self.lintdir, 'external.lint'))
-        result = self.lint.roll(self.files)
-        self.assertIsInstance(result, dict)
-        self.assertIn(self.path('foobar.js'), result.keys())
-        self.assertNotIn(self.path('no_foobar.js'), result.keys())
+def test_no_filter(lint, lintdir, files):
+    lint.read(os.path.join(lintdir, 'explicit_path.lint'))
+    result = lint.roll(files)
+    assert len(result) == 0
 
-        result = result[self.path('foobar.js')][0]
-        self.assertIsInstance(result, ResultContainer)
-        self.assertEqual(result.linter, 'ExternalLinter')
-
-    def test_no_filter(self):
-        self.lint.read(os.path.join(self.lintdir, 'explicit_path.lint'))
-        result = self.lint.roll(self.files)
-        self.assertEqual(len(result), 0)
-
-        self.lint.lintargs['use_filters'] = False
-        result = self.lint.roll(self.files)
-        self.assertEqual(len(result), 2)
+    lint.lintargs['use_filters'] = False
+    result = lint.roll(files)
+    assert len(result) == 2
 
 
 if __name__ == '__main__':
-    main()
+    sys.exit(pytest.main(['--verbose', __file__]))