diff --git a/.coveragerc b/.coveragerc index 7d111e74c..bcc99c18f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -2,7 +2,6 @@ omit = */pyshared/* */python?.?/* - */site-packages/nose/* */test/* exclude_lines = assert False diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5045a1b9c..f9cce8d23 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,95 +1,85 @@ name: ci on: [push, pull_request] jobs: - test-27: + test: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ ubuntu-latest ] + platform: [ubuntu-latest] + python-version: [2.7, 3.5, 3.6, 3.7, 3.8] + env: - NOSE_SHOW_SKIPPED: 1 - PY_COLOR: 1 + PY_COLORS: 1 + steps: - uses: actions/checkout@v2 - - name: Set up Python 2.7 + + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: - python-version: 2.7 - - uses: actions/cache@v1 - if: startsWith(runner.os, 'Linux') - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - uses: actions/cache@v1 - if: startsWith(runner.os, 'Windows') - with: - path: ~\AppData\Local\pip\Cache - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - name: Install base dependencies - run: | - python -m pip install --upgrade pip - pip install tox sphinx - - name: Test with tox - run: tox -e py27-test - test-3x: - runs-on: ${{ matrix.platform }} - strategy: - matrix: - platform: [ ubuntu-latest ] - python-version: [ 5, 6, 7, 8 ] - env: - NOSE_SHOW_SKIPPED: 1 - PY_COLOR: 1 - steps: - - uses: actions/checkout@v2 - - name: Set up Python 3.${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: 3.${{ matrix.python-version }} - - uses: actions/cache@v1 - if: startsWith(runner.os, 'Linux') - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - uses: actions/cache@v1 - if: startsWith(runner.os, 'Windows') - with: - path: ~\AppData\Local\pip\Cache - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - name: Install base dependencies - run: | - python -m pip install --upgrade pip - pip install tox sphinx - - name: Test, coverage, and flake8 with tox - if: matrix.python-version == '8' - run: | - tox -e py3${{ matrix.python-version }}-test - tox -e py3${{ matrix.python-version }}-cov - tox -e py3${{ matrix.python-version }}-flake8 - pip install codecov || true - codecov || true - - name: Test with tox - if: matrix.python-version != '8' - run: tox -e py3${{ matrix.python-version }}-test - docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python to build docs with Sphinx - uses: actions/setup-python@v2 - with: - python-version: 2.7 + python-version: ${{ matrix.python-version }} + - name: Install base dependencies run: | python -m pip install --upgrade pip python -m pip install tox sphinx + + - name: Test with tox + if: matrix.python-version != '3.8' + run: | + tox -e py-test + + - name: Test with tox and get coverage + if: matrix.python-version == '3.8' + run: | + tox -vv -e py-cov + + - name: Upload code coverage + if: matrix.python-version == '3.8' + run: | + pip install codecov || true + codecov || true + + test-docs: + runs-on: ubuntu-latest + + env: + PY_COLORS: 1 + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python 2.7 + uses: actions/setup-python@v2 + with: + python-version: 2.7 + + - name: Install base dependencies + run: | + python -m pip install --upgrade pip + python -m pip install tox sphinx + - name: Build and check docs using tox run: tox -e docs + + lint: + runs-on: ubuntu-latest + + env: + PY_COLORS: 1 + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install base dependencies + run: | + python -m pip install --upgrade pip + python -m pip install tox sphinx + + - name: Lint with flake8 + run: tox -e py-lint \ No newline at end of file diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index 11085223f..fd67bb395 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -5,28 +5,23 @@ on: jobs: test integration: runs-on: ubuntu-latest - strategy: - python-version: 3.8 + env: - NOSE_SHOW_SKIPPED: 1 - PY_COLOR: 1 - INTEGRATION_TEST: 1 + PY_COLORS: 1 + steps: - uses: actions/checkout@v2 + - name: Set up Python 3.8 uses: actions/setup-python@v2 with: python-version: 3.8 - - uses: actions/cache@v1 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- + - name: Install base dependencies run: | python -m pip install --upgrade pip - pip install tox + python -m pip install tox sphinx + - name: Test with tox run: | - tox -e py38-test \ No newline at end of file + tox -e int \ No newline at end of file diff --git a/.gitignore b/.gitignore index 241202b88..3a0340a3f 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,6 @@ htmlcov/ .coverage .coverage.* .cache -nosetests.xml coverage.xml *,cover .hypothesis/ diff --git a/appveyor.yml b/appveyor.yml index 00a3eb189..5a0f32135 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,9 +6,6 @@ skip_commits: message: /\[appveyor skip\]/ environment: - # Undocumented feature of nose-show-skipped. - NOSE_SHOW_SKIPPED: 1 - matrix: - PYTHON: C:\Python27 TOX_ENV: py27-test diff --git a/setup.cfg b/setup.cfg index 0660b2721..89649ed11 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,3 @@ -[nosetests] -verbosity=1 -logging-clear-handlers=1 - [flake8] min-version=2.7 accept-encodings=utf-8 diff --git a/setup.py b/setup.py index c50e65bf5..0e2cb332a 100755 --- a/setup.py +++ b/setup.py @@ -109,24 +109,33 @@ setup( ['colorama'] if (sys.platform == 'win32') else [] ), - tests_require=[ - 'beautifulsoup4', - 'flask', - 'mock', - 'pylast', - 'rarfile', - 'responses', - 'pyxdg', - 'python-mpd2', - 'discogs-client', - 'requests_oauthlib' - ] + ( - # Tests for the thumbnails plugin need pathlib on Python 2 too. - ['pathlib'] if (sys.version_info < (3, 4, 0)) else [] - ), - - # Plugin (optional) dependencies: extras_require={ + 'test': [ + 'beautifulsoup4', + 'coverage', + 'discogs-client', + 'flask', + 'mock', + 'pylast', + 'pytest', + 'python-mpd2', + 'pyxdg', + 'rarfile', + 'responses>=0.3.0', + 'requests_oauthlib', + ] + ( + # Tests for the thumbnails plugin need pathlib on Python 2 too. + ['pathlib'] if (sys.version_info < (3, 4, 0)) else [] + ), + 'lint': [ + 'flake8', + 'flake8-blind-except', + 'flake8-coding', + 'flake8-future-import', + 'pep8-naming', + ], + + # Plugin (optional) dependencies: 'absubmit': ['requests'], 'fetchart': ['requests', 'Pillow'], 'embedart': ['Pillow'], diff --git a/test/_common.py b/test/_common.py index 5412ab650..8e3b1dd18 100644 --- a/test/_common.py +++ b/test/_common.py @@ -44,7 +44,7 @@ beetsplug.__path__ = [os.path.abspath( RSRC = util.bytestring_path(os.path.join(os.path.dirname(__file__), 'rsrc')) PLUGINPATH = os.path.join(os.path.dirname(__file__), 'rsrc', 'beetsplug') -# Propagate to root logger so nosetest can capture it +# Propagate to root logger so the test runner can capture it log = logging.getLogger('beets') log.propagate = True log.setLevel(logging.DEBUG) diff --git a/test/test_parentwork.py b/test/test_parentwork.py index aa25c7f51..df6a98d79 100644 --- a/test/test_parentwork.py +++ b/test/test_parentwork.py @@ -17,6 +17,7 @@ from __future__ import division, absolute_import, print_function +import os import unittest from test.helper import TestHelper @@ -34,6 +35,9 @@ class ParentWorkTest(unittest.TestCase, TestHelper): self.unload_plugins() self.teardown_beets() + @unittest.skipUnless( + os.environ.get('INTEGRATION_TEST', '0') == '1', + 'integration testing not enabled') def test_normal_case(self): item = Item(path='/file', mb_workid=u'e27bda6e-531e-36d3-9cd7-b8ebc18e8c53') @@ -45,6 +49,9 @@ class ParentWorkTest(unittest.TestCase, TestHelper): self.assertEqual(item['mb_parentworkid'], u'32c8943f-1b27-3a23-8660-4567f4847c94') + @unittest.skipUnless( + os.environ.get('INTEGRATION_TEST', '0') == '1', + 'integration testing not enabled') def test_force(self): self.config['parentwork']['force'] = True item = Item(path='/file', @@ -58,6 +65,9 @@ class ParentWorkTest(unittest.TestCase, TestHelper): self.assertEqual(item['mb_parentworkid'], u'32c8943f-1b27-3a23-8660-4567f4847c94') + @unittest.skipUnless( + os.environ.get('INTEGRATION_TEST', '0') == '1', + 'integration testing not enabled') def test_no_force(self): self.config['parentwork']['force'] = True item = Item(path='/file', mb_workid=u'e27bda6e-531e-36d3-9cd7-\ @@ -72,6 +82,9 @@ class ParentWorkTest(unittest.TestCase, TestHelper): # test different cases, still with Matthew Passion Ouverture or Mozart # requiem + @unittest.skipUnless( + os.environ.get('INTEGRATION_TEST', '0') == '1', + 'integration testing not enabled') def test_direct_parent_work(self): mb_workid = u'2e4a3668-458d-3b2a-8be2-0b08e0d8243a' self.assertEqual(u'f04b42df-7251-4d86-a5ee-67cfa49580d1', diff --git a/tox.ini b/tox.ini index a62981ec8..e3476db1c 100644 --- a/tox.ini +++ b/tox.ini @@ -4,57 +4,30 @@ # and then run "tox" from this directory. [tox] -envlist = py27-test, py37-test, py27-flake8, docs - -# The exhaustive list of environments is: -# envlist = py{27,34,35}-{test,cov}, py{27,34,35}-flake8, docs +envlist = py27-test, py38-{cov,lint}, docs [_test] -deps = - beautifulsoup4 - flask - mock - nose - nose-show-skipped - pylast - rarfile - responses>=0.3.0 - pyxdg - python-mpd2 - coverage - discogs-client - requests_oauthlib +deps = .[test] -[_flake8] -deps = - flake8 - flake8-coding - flake8-future-import - flake8-blind-except - pep8-naming +[_lint] +deps = .[lint] files = beets beetsplug beet test setup.py docs [testenv] -passenv = - NOSE_SHOW_SKIPPED # Undocumented feature of nose-show-skipped. - INTEGRATION_TEST # set to 1 for integration tests deps = {test,cov}: {[_test]deps} - py27: pathlib - py{27,34,35,36,37,38}-flake8: {[_flake8]deps} + lint: {[_lint]deps} commands = - py27-cov: python -m nose --with-coverage {posargs} - py27-test: python -m nose {posargs} - py3{4,5,6,7,8}-cov: python -bb -m nose --with-coverage {posargs} - py3{4,5,6,7,8}-test: python -bb -m nose {posargs} - py27-flake8: flake8 {posargs} {[_flake8]files} - py34-flake8: flake8 {posargs} {[_flake8]files} - py35-flake8: flake8 {posargs} {[_flake8]files} - py36-flake8: flake8 {posargs} {[_flake8]files} - py37-flake8: flake8 {posargs} {[_flake8]files} - py38-flake8: flake8 {posargs} {[_flake8]files} + test: python -bb -m pytest {posargs} + cov: coverage run -m pytest {posargs} + lint: python -m flake8 {posargs} {[_lint]files} [testenv:docs] basepython = python2.7 deps = sphinx commands = sphinx-build -W -q -b html docs {envtmpdir}/html {posargs} + +[testenv:int] +deps = {[_test]deps} +setenv = INTEGRATION_TEST = 1 +commands = python -bb -m pytest {posargs} \ No newline at end of file