From 017635781d71783a3218dae426637a9ca91486d7 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Sun, 22 Aug 2021 19:34:28 +0100 Subject: [PATCH] Migrate to Github CI (#312) --- .appveyor.yml | 32 ----- .coveragerc | 13 -- .github/workflows/ci.yml | 130 ++++++++++++++++++ .mypy.ini | 46 +++++++ .travis.yml | 59 -------- Makefile | 10 +- aiohttp_devtools/__init__.py | 5 +- aiohttp_devtools/cli.py | 4 +- aiohttp_devtools/runserver/__init__.py | 3 +- aiohttp_devtools/runserver/config.py | 19 +-- aiohttp_devtools/runserver/log_handlers.py | 4 +- aiohttp_devtools/runserver/serve.py | 7 +- aiohttp_devtools/start/__init__.py | 3 +- aiohttp_devtools/start/template/__init__.py | 0 aiohttp_devtools/version.py | 5 - .../requirements.txt => requirements-dev.txt | 19 ++- setup.cfg | 17 +-- setup.py | 4 +- tests/check_tag.py | 10 +- tests/conftest.py | 2 +- tests/test_cli.py | 4 +- tests/test_runserver_main.py | 2 +- tests/test_runserver_watch.py | 2 +- tests/test_serve.py | 2 +- tests/test_start.py | 28 +--- 25 files changed, 232 insertions(+), 198 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .mypy.ini delete mode 100644 .travis.yml create mode 100644 aiohttp_devtools/start/template/__init__.py delete mode 100644 aiohttp_devtools/version.py rename tests/requirements.txt => requirements-dev.txt (67%) diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 7ccd7b51..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,32 +0,0 @@ -environment: - global: - # Ref: https://stackoverflow.com/a/48093971/595220 - # Don't run - # $ chcp 65001 - # as it might be harmful - PYTHONIOENCODING: utf-8 - matrix: - - PYTHON: "C:\\Python36" - - PYTHON: "C:\\Python36-x64" - - PYTHON: "C:\\Python37" - - PYTHON: "C:\\Python37-x64" - -services: -- postgresql - -install: -# Ensure the Git Submoduldes have been pulled down too -- git submodule update --init --recursive - -- "%PYTHON%\\python.exe -m pip install -U pip wheel setuptools . -r tests/requirements.txt" - -build_script: -- "%PYTHON%\\Scripts\\grablib.exe" -- "%PYTHON%\\python.exe -m setup sdist bdist_wheel" - -test_script: -- "%PYTHON%\\python.exe -m setup check -rms" -- "%PYTHON%\\python.exe -m pytest --cov=aiohttp_devtools --cov-report term-missing:skip-covered --cov-report xml --junitxml junit-test-results.xml --duration 5 -m \"not isort\" -vv --fulltrace" - -artifacts: -- path: dist\* diff --git a/.coveragerc b/.coveragerc index 93fb89b0..398ff08a 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,15 +1,2 @@ [run] -source = aiohttp_devtools branch = True -concurrency = multiprocessing -omit = - # __main__ is trivial and hard to test properly - */__main__.py - -[report] -precision = 2 -exclude_lines = - pragma: no cover - - raise NotImplementedError - raise NotImplemented diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..92031306 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,130 @@ +name: CI + +on: + push: + branches: + - master + - '[0-9].[0-9]+' # matches to backport branches, e.g. 3.6 + tags: [ 'v*' ] + pull_request: + branches: + - master + - '[0-9].[0-9]+' + schedule: + - cron: '0 6 * * *' # Daily 6AM UTC build + + +jobs: + + lint: + name: Linter + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Cache PyPI + uses: actions/cache@v2 + with: + key: pip-lint-${{ hashFiles('requirements-dev.txt') }} + path: ~/.cache/pip + restore-keys: | + pip-lint- + - name: Install dependencies + uses: py-actions/py-dependency-install@v2 + with: + path: requirements-dev.txt + - name: Install itself + run: | + pip install . + - name: Lint + run: | + make lint + - name: Prepare twine checker + run: | + pip install -U twine wheel + python setup.py sdist bdist_wheel + - name: Run twine checker + run: | + twine check dist/* + + test: + name: Test + needs: lint + strategy: + matrix: + pyver: [3.6, 3.7] + os: [ubuntu, macos] + #include: + # - pyver: pypy3 + # os: ubuntu + runs-on: ${{ matrix.os }}-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python ${{ matrix.pyver }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.pyver }} + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" # - name: Cache + - name: Cache PyPI + uses: actions/cache@v2 + with: + key: pip-ci-${{ runner.os }}-${{ matrix.pyver }}-${{ hashFiles('requirements-dev.txt') }} + path: ${{ steps.pip-cache.outputs.dir }} + restore-keys: | + pip-ci-${{ runner.os }}-${{ matrix.pyver }}- + - name: Install dependencies + uses: py-actions/py-dependency-install@v2 + with: + path: requirements-dev.txt + - name: Install JS dependencies + run: grablib + - name: Run unittests + env: + COLOR: 'yes' + run: | + pytest + python -m coverage xml + - name: Upload coverage + uses: codecov/codecov-action@v1 + with: + file: ./coverage.xml + flags: unit + fail_ci_if_error: false + + deploy: + name: Deploy + runs-on: ubuntu-latest + needs: test + # Run only on pushing a tag + if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Install dependencies + run: + python -m pip install -U pip wheel twine + - name: Install JS dependencies + run: grablib + - name: Make dists + run: + python setup.py sdist bdist_wheel + - name: PyPI upload + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: pAzJhAD5HNzxvbNg/UwquwPXOp6V27gi4MpqCs6mK2Hy9h3Ii8vVWzEUx06v2aqT5b3P7FDBRW8+t9oL+aS/dZxeOtA/jNzROxMhFtRbpv1F/Mvd6ocz7yb3yg9WUlc7bhuyN6GUxsw4esATElQygqZucXRGsg+yauiTTd2X1CK6zrTz7/5lhF5H41oMzBKBZgvEUjDzaTs+C+B0bEifADVsI8QDa4EUTzCc93qf2z1jllDd/Jww9MK6xdBJJCoXjfBtWSjnoBANN/Ikthy8yY2PXvbLKH7K4Ri+ED72tLXThuTEsmquj20TnR30Hpm0LjwfdZ1+2O0X0PMyjMIRoATR0D9XdSP36FZs19zyRRFwHYKxZvXKSv+rZxz1rZYbbPojNW/498zlWcI8R9TxqPg/6dnrO1StnltLmN784AVBQr172CX/Ji3BF1bVytgdKqstGVN6d1JJWPuFVNfGpVHJJZEEuOBndK7yoSSV4zMva5wXplETVyGWfPiqvQCtylq8IatXbFxA0trCMW1kQEwBMBLbYrqx6ZIHQJ4Z46ng7OIYdRPod7fkK7e0lXU7OexfXad/UOWfkayOG1C93MWxeVho8ZQrBCdrHd1a5iujAfW8pk7Al8f2gS8L7nZTXUlkWK2ppX9PDOv1O0frtFc1prje+9AzROFC8UXxJk8= + run: | + twine upload dist/* diff --git a/.mypy.ini b/.mypy.ini new file mode 100644 index 00000000..e1f44568 --- /dev/null +++ b/.mypy.ini @@ -0,0 +1,46 @@ +[mypy] +files = aiohttp_devtools, tests +check_untyped_defs = True +follow_imports_for_stubs = True +#disallow_any_decorated = True +disallow_any_generics = True +#disallow_incomplete_defs = True +disallow_subclassing_any = True +#disallow_untyped_calls = True +disallow_untyped_decorators = True +#disallow_untyped_defs = True +implicit_reexport = False +no_implicit_optional = True +show_error_codes = True +strict_equality = True +warn_incomplete_stub = True +warn_redundant_casts = True +warn_unreachable = True +warn_unused_ignores = True +disallow_any_unimported = True +warn_return_any = True + +[mypy-tests.*] +ignore_errors = True +disallow_any_decorated = False +disallow_untyped_calls = False +disallow_untyped_defs = False + +[mypy-aiohttp_devtools.start.*] +ignore_errors = True + +[mypy-aiohttp_devtools.logs] +ignore_errors = True + +[mypy-aiohttp_devtools.runserver.*] +ignore_errors = True + + +[mypy-aiohttp_debugtoolbar.*] +ignore_missing_imports = True + +[mypy-devtools.*] +ignore_missing_imports = True + +[mypy-pygments.*] +ignore_missing_imports = True diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 261e9b08..00000000 --- a/.travis.yml +++ /dev/null @@ -1,59 +0,0 @@ -language: python - -cache: pip - -services: -- postgresql - -matrix: - include: - - python: '3.6' - env: 'AIOHTTP_VERSION=aiohttp==3.5.4' - - python: '3.7' - dist: xenial - sudo: required - env: 'AIOHTTP_VERSION=aiohttp==3.5.4' - - python: '3.7' - dist: xenial - sudo: required - env: 'AIOHTTP_VERSION=https://github.com/aio-libs/aiohttp/archive/master.zip' - - python: '3.8' - dist: xenial - sudo: required - env: 'AIOHTTP_VERSION=aiohttp==3.5.4' - - python: '3.9' - env: 'AIOHTTP_VERSION=aiohttp==3.5.4' - - allow_failures: - - python: '3.9' - - env: 'AIOHTTP_VERSION=https://github.com/aio-libs/aiohttp/archive/master.zip' - -install: -- make install -- pip install -U "${AIOHTTP_VERSION}" -- pip freeze - -script: -- make lint -- make test -- ./tests/check_tag.py -#- make docs -- pip freeze -- ls -lha - -after_success: -- bash <(curl -s https://codecov.io/bash) - -deploy: - provider: pypi - user: aio-libs-bot - password: - secure: >- - pAzJhAD5HNzxvbNg/UwquwPXOp6V27gi4MpqCs6mK2Hy9h3Ii8vVWzEUx06v2aqT5b3P7FDBRW8+t9oL+aS/dZxeOtA/jNzROxMhFtRbpv1F/Mvd6ocz7yb3yg9WUlc7bhuyN6GUxsw4esATElQygqZucXRGsg+yauiTTd2X1CK6zrTz7/5lhF5H41oMzBKBZgvEUjDzaTs+C+B0bEifADVsI8QDa4EUTzCc93qf2z1jllDd/Jww9MK6xdBJJCoXjfBtWSjnoBANN/Ikthy8yY2PXvbLKH7K4Ri+ED72tLXThuTEsmquj20TnR30Hpm0LjwfdZ1+2O0X0PMyjMIRoATR0D9XdSP36FZs19zyRRFwHYKxZvXKSv+rZxz1rZYbbPojNW/498zlWcI8R9TxqPg/6dnrO1StnltLmN784AVBQr172CX/Ji3BF1bVytgdKqstGVN6d1JJWPuFVNfGpVHJJZEEuOBndK7yoSSV4zMva5wXplETVyGWfPiqvQCtylq8IatXbFxA0trCMW1kQEwBMBLbYrqx6ZIHQJ4Z46ng7OIYdRPod7fkK7e0lXU7OexfXad/UOWfkayOG1C93MWxeVho8ZQrBCdrHd1a5iujAfW8pk7Al8f2gS8L7nZTXUlkWK2ppX9PDOv1O0frtFc1prje+9AzROFC8UXxJk8= - distributions: sdist bdist_wheel - # skip_cleanup: true is required to include livereload.js - skip_cleanup: true - on: - tags: true - python: 3.6 - condition: "$AIOHTTP_VERSION = aiohttp==3.5.4" diff --git a/Makefile b/Makefile index ccc2471c..542fcba6 100644 --- a/Makefile +++ b/Makefile @@ -7,17 +7,11 @@ install: pip install -r tests/requirements.txt grablib -.PHONY: isort -isort: - isort -rc -w 120 aiohttp_devtools - isort -rc -w 120 tests - .PHONY: lint lint: python setup.py check -rms - flake8 aiohttp_devtools/ tests/ - isort -rc -w 120 --check-only aiohttp_devtools - isort -rc -w 120 --check-only tests + mypy + flake8 .PHONY: test test: diff --git a/aiohttp_devtools/__init__.py b/aiohttp_devtools/__init__.py index ae2c2fd5..7e0dc0e8 100644 --- a/aiohttp_devtools/__init__.py +++ b/aiohttp_devtools/__init__.py @@ -1,4 +1 @@ -from .version import VERSION - -# to match aiohttp -__version__ = str(VERSION) +__version__ = "0.13.1" diff --git a/aiohttp_devtools/cli.py b/aiohttp_devtools/cli.py index 6967bb6a..166d2e7a 100644 --- a/aiohttp_devtools/cli.py +++ b/aiohttp_devtools/cli.py @@ -4,13 +4,13 @@ import click +from . import __version__ from .exceptions import AiohttpDevException from .logs import main_logger, setup_logging from .runserver import INFER_HOST, run_app from .runserver import runserver as _runserver from .runserver import serve_static from .start import StartProject, check_dir_clean -from .version import VERSION _dir_existing = click.Path(exists=True, dir_okay=True, file_okay=False) _file_dir_existing = click.Path(exists=True, dir_okay=True, file_okay=True) @@ -18,7 +18,7 @@ @click.group() -@click.version_option(VERSION, '-V', '--version', prog_name='aiohttp-devtools') +@click.version_option(__version__, "-V", "--version", prog_name="aiohttp-devtools") def cli(): pass diff --git a/aiohttp_devtools/runserver/__init__.py b/aiohttp_devtools/runserver/__init__.py index 6c902225..2729c811 100644 --- a/aiohttp_devtools/runserver/__init__.py +++ b/aiohttp_devtools/runserver/__init__.py @@ -1,3 +1,4 @@ -# flake8: noqa from .config import INFER_HOST from .main import run_app, runserver, serve_static + +__all__ = ("INFER_HOST", "run_app", "runserver", "serve_static") diff --git a/aiohttp_devtools/runserver/config.py b/aiohttp_devtools/runserver/config.py index c2a27d4f..5380cfec 100644 --- a/aiohttp_devtools/runserver/config.py +++ b/aiohttp_devtools/runserver/config.py @@ -4,6 +4,7 @@ import sys from importlib import import_module from pathlib import Path +from typing import Optional from aiohttp import web @@ -29,21 +30,21 @@ class Config: def __init__(self, *, app_path: str = '.', - root_path: str = None, + root_path: Optional[str] = None, verbose: bool = False, - static_path: str = None, - python_path: str = None, + static_path: Optional[str] = None, + python_path: Optional[str] = None, static_url: str = '/static/', livereload: bool = True, debug_toolbar: bool = False, # TODO set True once debug toolbar is fixed - app_factory_name: str = None, + app_factory_name: Optional[str] = None, host: str = INFER_HOST, main_port: int = 8000, - aux_port: int = None): + aux_port: Optional[int] = None): if root_path: self.root_path = Path(root_path).resolve() logger.debug('Root path specified: %s', self.root_path) - self.watch_path = self.root_path + self.watch_path: Optional[Path] = self.root_path else: logger.debug('Root path not specified, using current working directory') self.root_path = Path('.').resolve() @@ -70,7 +71,7 @@ def __init__(self, *, logger.debug('config loaded:\n%s', self) @property - def static_path_str(self): + def static_path_str(self) -> Optional[str]: return self.static_path and str(self.static_path) def _find_app_path(self, app_path: str) -> Path: @@ -95,7 +96,7 @@ def _find_app_path(self, app_path: str) -> Path: raise AdevConfigError('unable to find a recognised default file ("app.py" or "main.py") ' 'in the directory "%s"' % app_path) - def _resolve_path(self, _path: str, check: str, arg_name: str): + def _resolve_path(self, _path: Optional[str], check: str, arg_name: str): if _path is None: return @@ -171,7 +172,7 @@ async def load_app(self, app_factory): app = app_factory() if asyncio.iscoroutine(app): - app = await app + app = await app # type: ignore[misc] if not isinstance(app, web.Application): raise AdevConfigError('app factory "{.app_factory_name}" returned "{.__class__.__name__}" not an ' diff --git a/aiohttp_devtools/runserver/log_handlers.py b/aiohttp_devtools/runserver/log_handlers.py index f4498b76..ad3a0a93 100644 --- a/aiohttp_devtools/runserver/log_handlers.py +++ b/aiohttp_devtools/runserver/log_handlers.py @@ -1,6 +1,7 @@ import json import warnings from datetime import datetime, timedelta +from typing import cast from aiohttp.abc import AbstractAccessLogger @@ -9,7 +10,7 @@ class _AccessLogger(AbstractAccessLogger): - prefix = NotImplemented + prefix: str def get_msg(self, request, response, time): raise NotImplementedError() @@ -89,6 +90,7 @@ def parse_body(v, name): try: return json.loads(v) except UnicodeDecodeError: + v = cast(bytes, v) # UnicodeDecodeError only occurs on bytes. warnings.warn('UnicodeDecodeError parsing ' + name, UserWarning) # bytes which cause UnicodeDecodeError can cause problems later on return v.decode(errors='ignore') diff --git a/aiohttp_devtools/runserver/serve.py b/aiohttp_devtools/runserver/serve.py index 9df739a5..54cce228 100644 --- a/aiohttp_devtools/runserver/serve.py +++ b/aiohttp_devtools/runserver/serve.py @@ -3,6 +3,7 @@ import json import mimetypes import sys +from errno import EADDRINUSE from pathlib import Path from typing import Optional @@ -87,10 +88,10 @@ async def check_port_open(port, loop, delay=1): try: server = await loop.create_server(asyncio.Protocol(), host=HOST, port=port) except OSError as e: - if e.errno != 98: # pragma: no cover + if e.errno != EADDRINUSE: raise dft_logger.warning('port %d is already in use, waiting %d...', port, i) - await asyncio.sleep(delay, loop=loop) + await asyncio.sleep(delay) else: server.close() await server.wait_closed() @@ -143,7 +144,7 @@ async def start_main_app(config: Config, app_factory, loop): WS = 'websockets' -async def src_reload(app, path: str = None): +async def src_reload(app, path: Optional[str] = None): """ prompt each connected browser to reload by sending websocket message. diff --git a/aiohttp_devtools/start/__init__.py b/aiohttp_devtools/start/__init__.py index 37c9ed10..9cb05212 100644 --- a/aiohttp_devtools/start/__init__.py +++ b/aiohttp_devtools/start/__init__.py @@ -1,2 +1,3 @@ -# flake8: noqa from .main import StartProject, check_dir_clean + +__all__ = ("StartProject", "check_dir_clean") diff --git a/aiohttp_devtools/start/template/__init__.py b/aiohttp_devtools/start/template/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/aiohttp_devtools/version.py b/aiohttp_devtools/version.py deleted file mode 100644 index 0736f52a..00000000 --- a/aiohttp_devtools/version.py +++ /dev/null @@ -1,5 +0,0 @@ -from distutils.version import StrictVersion - -__all__ = ['VERSION'] - -VERSION = StrictVersion('0.13.1') diff --git a/tests/requirements.txt b/requirements-dev.txt similarity index 67% rename from tests/requirements.txt rename to requirements-dev.txt index 413bf57e..0fbb36e5 100644 --- a/tests/requirements.txt +++ b/requirements-dev.txt @@ -1,17 +1,16 @@ +-e . aiohttp_debugtoolbar==0.5.0 -click==7.0.0 -coverage==4.5.3 +click==8.0.1 +coverage==5.5 docutils==0.14 -flake8==3.7.7 +flake8==3.9.2 grablib==0.8 -isort==4.3.20 -pycodestyle==2.5.0 -pyflakes==2.1.1 -pytest==4.4.1 +mypy==0.910 +pytest==6.2.4 pytest-aiohttp==0.3.0 -pytest-cov==2.6.1 +pytest-cov==2.12.1 pytest-mock==1.10.4 -pytest-sugar==0.9.2 +pytest-sugar==0.9.4 pytest-timeout==1.3.3 pytest-toolbox==0.4 pytest-xdist==1.28.0 @@ -21,5 +20,5 @@ Sphinx==3.0.4 aiohttp==3.5.4 aiohttp-jinja2==1.2.0 aiohttp-session[secure]==2.9.0 -asyncpg==0.21.0 +jinja2==2.11.3 pydantic==0.25;python_version>="3.6" diff --git a/setup.cfg b/setup.cfg index 9ba0f0ca..197c3d7c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,16 +1,15 @@ [tool:pytest] -testpaths = tests -timeout = 10 -isort_ignore = - aiohttp_devtools/start/template/*.py - tests/test_runserver_main.py +addopts = --cov=aiohttp_devtools --cov-report xml --cov-report html --cov-report term +markers = boxed: mark tests as boxed +testpaths = tests/ filterwarnings = error - ignore::DeprecationWarning:aiohttp_debugtoolbar.tbtools.tbtools + ignore::DeprecationWarning:aiohttp_debugtoolbar ignore::UserWarning:psycopg2 ignore::DeprecationWarning:aiopg ignore::DeprecationWarning:jinja2 ignore::DeprecationWarning:isort +xfail_strict = true [flake8] max-line-length = 120 @@ -19,9 +18,3 @@ exclude = aiohttp_devtools/start/template [bdist_wheel] python-tag = py36.py37.py38.py39 - -[isort] -known_first_party=aiohttp_devtools -known_third_party= - watchgod - pydantic diff --git a/setup.py b/setup.py index 022ac124..00345ed4 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ long_description = THIS_DIR.joinpath('README.rst').read_text() # avoid loading the package before requirements are installed: -version = SourceFileLoader('version', 'aiohttp_devtools/version.py').load_module() +version = SourceFileLoader("__version__", "aiohttp_devtools/__init__.py").load_module() package = THIS_DIR.joinpath('aiohttp_devtools/start') @@ -25,7 +25,7 @@ setup( name=name, - version=str(version.VERSION), + version=version.__version__, description='Dev tools for aiohttp', long_description=long_description, classifiers=[ diff --git a/tests/check_tag.py b/tests/check_tag.py index f0d2217b..c4a35d90 100755 --- a/tests/check_tag.py +++ b/tests/check_tag.py @@ -2,14 +2,16 @@ import os import sys -from aiohttp_devtools.version import VERSION +from aiohttp_devtools import __version__ git_tag = os.getenv('TRAVIS_TAG') if git_tag: - if git_tag.lower().lstrip('v') != str(VERSION).lower(): - print('✖ "TRAVIS_TAG" environment variable does not match package version: "%s" vs. "%s"' % (git_tag, VERSION)) + if git_tag.lower().lstrip("v") != __version__: + m = '✖ "TRAVIS_TAG" environment variable does not match package version: "{}" vs. "{}"' + print(m.format(git_tag, __version__)) sys.exit(1) else: - print('✓ "TRAVIS_TAG" environment variable matches package version: "{}" vs. "%s"'.format(git_tag, VERSION)) + m = '✓ "TRAVIS_TAG" environment variable matches package version: "{}" vs. "{}"' + print(m.format(git_tag, __version__)) else: print('✓ "TRAVIS_TAG" not defined') diff --git a/tests/conftest.py b/tests/conftest.py index 8e29b4a4..674ae0b8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -35,6 +35,6 @@ def create_app(): def create_future(result=None): - f = Future() + f: Future[None] = Future() f.set_result(result) return f diff --git a/tests/test_cli.py b/tests/test_cli.py index ac53d378..9bbd0e4c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -30,7 +30,7 @@ def test_serve_no_args(): runner = CliRunner() result = runner.invoke(cli, ['serve']) assert result.exit_code == 2 - assert 'Error: Missing argument "PATH"' in result.output + assert "Error: Missing argument 'PATH'" in result.output def test_runserver(mocker): @@ -103,7 +103,7 @@ def test_start_no_args(): runner = CliRunner() result = runner.invoke(cli, ['start']) assert result.exit_code == 2 - assert 'Error: Missing argument "PATH"' in result.output + assert "Error: Missing argument 'PATH'" in result.output def test_start_help(): diff --git a/tests/test_runserver_main.py b/tests/test_runserver_main.py index c0c893ae..87b868fe 100644 --- a/tests/test_runserver_main.py +++ b/tests/test_runserver_main.py @@ -181,7 +181,7 @@ async def hello(request): mock_modify_main_app.assert_called_with(mock.ANY, config) -@pytest.yield_fixture +@pytest.fixture def aux_cli(aiohttp_client, loop): app = create_auxiliary_app(static_path='.') cli = loop.run_until_complete(aiohttp_client(app)) diff --git a/tests/test_runserver_watch.py b/tests/test_runserver_watch.py index e9d2e449..c7fef2d6 100644 --- a/tests/test_runserver_watch.py +++ b/tests/test_runserver_watch.py @@ -168,7 +168,7 @@ def test_stop_process_clean(mocker): @non_windows_test # There's no signals in Windows -def test_stop_process_dirty(mocker): +async def test_stop_process_dirty(mocker): mock_kill = mocker.patch('aiohttp_devtools.runserver.watch.os.kill') mocker.patch('aiohttp_devtools.runserver.watch.awatch') app_task = AppTask(MagicMock()) diff --git a/tests/test_serve.py b/tests/test_serve.py index edb8b948..b7005285 100644 --- a/tests/test_serve.py +++ b/tests/test_serve.py @@ -6,7 +6,7 @@ from aiohttp_devtools.runserver import serve_static -@pytest.yield_fixture +@pytest.fixture def cli(loop, tmpworkdir, aiohttp_client): asyncio.set_event_loop(loop) app, _, _ = serve_static(static_path=str(tmpworkdir), livereload=False) diff --git a/tests/test_start.py b/tests/test_start.py index 7d13cda9..9add83f2 100644 --- a/tests/test_start.py +++ b/tests/test_start.py @@ -1,6 +1,3 @@ -import platform -import sys - import aiohttp import pytest from pytest_toolbox import mktree @@ -10,29 +7,7 @@ from aiohttp_devtools.runserver.serve import modify_main_app from aiohttp_devtools.start import StartProject -IS_WINDOWS = platform.system() == 'Windows' - - -def test_start_simple(tmpdir, smart_caplog): - StartProject(path=str(tmpdir), name='foobar') - assert {p.basename for p in tmpdir.listdir()} == { - 'app', - 'requirements.txt', - 'README.md', - 'static', - } - if IS_WINDOWS: - log_path = r'"C:\Users\appveyor\AppData\Local\Temp\..."' - log_normalizers = (r'"C:\\Users\\appveyor\\AppData\\Local\\Temp\\.*?"', log_path.replace('\\', r'\\')) - else: - log_path = '"/tmp/..."' - log_normalizers = ('"/tmp/.*?"', log_path) - assert """\ -adev.main INFO: Starting new aiohttp project "foobar" at {} -adev.main INFO: project created, 13 files generated\n""".format(log_path) == smart_caplog(log_normalizers) - -@pytest.mark.skipif(sys.version_info < (3, 6), reason='start app requires python >= 3.6') @pytest.mark.boxed async def test_start_run(tmpdir, loop, aiohttp_client, smart_caplog): StartProject(path=str(tmpdir.join('the-path')), name='foobar') @@ -42,10 +17,11 @@ async def test_start_run(tmpdir, loop, aiohttp_client, smart_caplog): 'requirements.txt', 'README.md', 'static', + '__init__.py', } assert """\ adev.main INFO: Starting new aiohttp project "foobar" at "//the-path" -adev.main INFO: project created, 13 files generated\n""" == smart_caplog.log.replace(str(tmpdir), '/') +adev.main INFO: project created, 14 files generated\n""" == smart_caplog.log.replace(str(tmpdir), '/') config = Config(app_path='the-path/app/', root_path=str(tmpdir), static_path='.') app_factory = config.import_app_factory() app = await app_factory()