diff --git a/.dockerignore b/.dockerignore index 38d67d5..9a59c66 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,5 @@ bin/ venv/ -.git/ .buildozer/ .pytest_cache/ .tox/ diff --git a/.gitignore b/.gitignore index 04bdc1f..2dd84ee 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ bin/ build/ dist/ *.egg-info/ +htmlcov/ +.coverage +.coverage.* diff --git a/.travis.yml b/.travis.yml index ec4490e..3f289da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,24 +4,15 @@ language: generic services: - docker + - xvfb env: - global: - - DISPLAY=:99.0 matrix: - TAG=zbarcam-linux DOCKERFILE=dockerfiles/Dockerfile-linux COMMAND='make test' - - TAG=zbarcam-linux DOCKERFILE=dockerfiles/Dockerfile-linux COMMAND='make uitest' - TAG=zbarcam-android DOCKERFILE=dockerfiles/Dockerfile-android COMMAND='buildozer android debug' -before_install: - - sudo apt update -qq > /dev/null - - sudo apt install --yes --no-install-recommends xvfb - -install: - - docker build --tag=$TAG --file=$DOCKERFILE --build-arg CI . - before_script: - - sh -e /etc/init.d/xvfb start + - docker build --tag=$TAG --file=$DOCKERFILE --build-arg CI . script: - - travis_wait docker run -e DISPLAY -e CI -v /tmp/.X11-unix:/tmp/.X11-unix $TAG $COMMAND + - travis_wait 30 docker run --env-file dockerfiles/env.list -v /tmp/.X11-unix:/tmp/.X11-unix $TAG $COMMAND diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b1bb3f..f11bc2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## [2019.1020] + + - Setup coverage testing + - Bump to `xcamera>=2019.928` + - Continuous integration improvements + ## [2019.0910] - Use new `xcamera` from PyPI diff --git a/Makefile b/Makefile index 9b92db2..f620f4e 100644 --- a/Makefile +++ b/Makefile @@ -1,55 +1,69 @@ -VENV_NAME=venv -PIP=$(VENV_NAME)/bin/pip +VIRTUAL_ENV ?= venv +PIP=$(VIRTUAL_ENV)/bin/pip TOX=`which tox` -GARDEN=$(VENV_NAME)/bin/garden -PYTHON=$(VENV_NAME)/bin/python -ISORT=$(VENV_NAME)/bin/isort -FLAKE8=$(VENV_NAME)/bin/flake8 +PYTHON=$(VIRTUAL_ENV)/bin/python +ISORT=$(VIRTUAL_ENV)/bin/isort +FLAKE8=$(VIRTUAL_ENV)/bin/flake8 +PYTEST=$(VIRTUAL_ENV)/bin/pytest TWINE=`which twine` SOURCES=src/ tests/ setup.py setup_meta.py # using full path so it can be used outside the root dir SPHINXBUILD=$(shell realpath venv/bin/sphinx-build) DOCS_DIR=doc SYSTEM_DEPENDENCIES= \ - libpython$(PYTHON_VERSION)-dev \ + build-essential \ + ccache \ + cmake \ + curl \ + git \ libsdl2-dev \ + libsdl2-image-dev \ + libsdl2-mixer-dev \ + libsdl2-ttf-dev \ + libpython3.6-dev \ + libpython$(PYTHON_VERSION)-dev \ libzbar-dev \ + pkg-config \ + python3.6 \ + python3.6-dev \ + python$(PYTHON_VERSION) \ + python$(PYTHON_VERSION)-dev \ tox \ virtualenv -OS=$(shell lsb_release -si) +OS=$(shell lsb_release -si 2>/dev/null || uname) PYTHON_MAJOR_VERSION=3 -PYTHON_MINOR_VERSION=6 +PYTHON_MINOR_VERSION=7 PYTHON_VERSION=$(PYTHON_MAJOR_VERSION).$(PYTHON_MINOR_VERSION) +PYTHON_MAJOR_MINOR=$(PYTHON_MAJOR_VERSION)$(PYTHON_MINOR_VERSION) PYTHON_WITH_VERSION=python$(PYTHON_VERSION) all: system_dependencies virtualenv -venv: - test -d venv || virtualenv -p $(PYTHON_WITH_VERSION) venv +system_dependencies: +ifeq ($(OS), Ubuntu) + sudo apt install --yes --no-install-recommends $(SYSTEM_DEPENDENCIES) +endif -virtualenv: venv +$(VIRTUAL_ENV): + virtualenv -p $(PYTHON_WITH_VERSION) $(VIRTUAL_ENV) $(PIP) install Cython==0.28.6 - $(PIP) install -r requirements/requirements.txt + $(PIP) install -r requirements.txt + +virtualenv: $(VIRTUAL_ENV) virtualenv/test: virtualenv $(PIP) install -r requirements/requirements-test.txt -system_dependencies: -ifeq ($(OS), Ubuntu) - sudo apt install --yes --no-install-recommends $(SYSTEM_DEPENDENCIES) -endif - -run/linux: virtualenv +run: virtualenv $(PYTHON) src/main.py -run: run/linux - test: $(TOX) + @if test -n "$$CI"; then .tox/py$(PYTHON_MAJOR_MINOR)/bin/coveralls; fi; \ -uitest: virtualenv/test - PYTHONPATH=src $(PYTHON) -m unittest discover --top-level-directory=. --start-directory=tests/ui/ +pytest: virtualenv/test + PYTHONPATH=src $(PYTEST) --cov src/ --cov-report html tests/ lint/isort-check: virtualenv/test $(ISORT) --check-only --recursive --diff $(SOURCES) @@ -65,7 +79,7 @@ lint: lint/isort-check lint/flake8 docs/clean: rm -rf $(DOCS_DIR)/build/ -docs: +docs: virtualenv cd $(DOCS_DIR) && SPHINXBUILD=$(SPHINXBUILD) make html release/clean: @@ -80,9 +94,21 @@ release/upload: $(TWINE) upload dist/* clean: release/clean docs/clean - py3clean src/ - find src/ -type d -name "__pycache__" -exec rm -r {} + - find src/ -type d -name "*.egg-info" -exec rm -r {} + + py3clean . + find . -type d -name "__pycache__" -exec rm -r {} + + find . -type d -name "*.egg-info" -exec rm -r {} + clean/all: clean - rm -rf $(VENV_NAME) .tox/ + rm -rf $(VIRTUAL_ENV) .tox/ + +docker/build: + docker build --tag=zbarcam-linux --file=dockerfiles/Dockerfile-linux . + +docker/run/test: + docker run --env-file dockerfiles/env.list -v /tmp/.X11-unix:/tmp/.X11-unix zbarcam-linux 'make test' + +docker/run/app: + docker run --env-file dockerfiles/env.list -v /tmp/.X11-unix:/tmp/.X11-unix --device=/dev/video0:/dev/video0 zbarcam-linux 'make run' + +docker/run/shell: + docker run --env-file dockerfiles/env.list -v /tmp/.X11-unix:/tmp/.X11-unix --device=/dev/video0:/dev/video0 -it --rm zbarcam-linux diff --git a/README.md b/README.md index 1db05e4..98a7f47 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # zbarcam [![Build Status](https://travis-ci.org/kivy-garden/zbarcam.svg?branch=develop)](https://travis-ci.org/kivy-garden/zbarcam) +[![Coverage Status](https://coveralls.io/repos/github/kivy-garden/zbarcam/badge.svg?branch=develop)](https://coveralls.io/github/kivy-garden/zbarcam?branch=develop) [![PyPI version](https://badge.fury.io/py/zbarcam.svg)](https://badge.fury.io/py/zbarcam) [![Documentation Status](https://readthedocs.org/projects/zbarcam/badge/?version=latest)](https://zbarcam.readthedocs.io/en/latest/?badge=latest) @@ -37,7 +38,7 @@ make system_dependencies Install zbarcam: ```sh -pip install --upgrade zbarcam +pip install zbarcam ``` Then import it in your Python code via: ```python diff --git a/buildozer.spec b/buildozer.spec index 28aed95..16997e2 100644 --- a/buildozer.spec +++ b/buildozer.spec @@ -44,7 +44,7 @@ requirements = Pillow==5.2.0, python3, pyzbar==0.1.8, - xcamera + xcamera==2019.928 # (str) Custom source folders for requirements diff --git a/dockerfiles/Dockerfile-android b/dockerfiles/Dockerfile-android index bf9c1b7..3b0c08b 100644 --- a/dockerfiles/Dockerfile-android +++ b/dockerfiles/Dockerfile-android @@ -17,7 +17,7 @@ ENV WORK_DIR="${HOME_DIR}" \ ENV DOCKERFILES_VERSION="v20190902" \ DOCKERFILES_URL="https://raw.githubusercontent.com/AndreMiras/dockerfiles" ENV MAKEFILES_URL="${DOCKERFILES_URL}/${DOCKERFILES_VERSION}/buildozer_android" -ENV BUILDOZER_VERSION="182d13f" +ENV BUILDOZER_VERSION="81c31c4" # configure locale @@ -29,7 +29,7 @@ ENV LANG="en_US.UTF-8" \ LC_ALL="en_US.UTF-8" # install system dependencies -RUN apt install -qq --yes --no-install-recommends \ +RUN apt update -qq > /dev/null && apt install -qq --yes --no-install-recommends \ autoconf \ automake \ ca-certificates \ @@ -54,20 +54,18 @@ RUN apt install -qq --yes --no-install-recommends \ xz-utils \ zip -# prepare non root env -RUN useradd --create-home --shell /bin/bash ${USER} -# with sudo access and no password -RUN usermod -append --groups sudo ${USER} -RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers +# prepare non root env, with sudo access and no password +RUN useradd --create-home --shell /bin/bash ${USER} && \ + usermod -append --groups sudo ${USER} && \ + echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers USER ${USER} WORKDIR ${WORK_DIR} -# install buildozer and dependencies -RUN curl --location --progress-bar ${MAKEFILES_URL}/buildozer.mk --output buildozer.mk -RUN make -f buildozer.mk -# enforces buildozer master until next release -RUN pip3 install --upgrade https://github.com/kivy/buildozer/archive/${BUILDOZER_VERSION}.zip +# install buildozer & dependencies and enforces buildozer master until next release +RUN curl --location --progress-bar ${MAKEFILES_URL}/buildozer.mk --output buildozer.mk && \ + make -f buildozer.mk && \ + pip3 install --upgrade https://github.com/kivy/buildozer/archive/${BUILDOZER_VERSION}.zip COPY . ${WORK_DIR} # limits the amount of logs for Travis diff --git a/dockerfiles/Dockerfile-linux b/dockerfiles/Dockerfile-linux index 237f39c..822fa4d 100644 --- a/dockerfiles/Dockerfile-linux +++ b/dockerfiles/Dockerfile-linux @@ -26,37 +26,21 @@ ENV LANG="en_US.UTF-8" \ # install system dependencies RUN apt install --yes --no-install-recommends \ - build-essential \ - ccache \ - cmake \ - curl \ - libsdl2-dev \ - libsdl2-image-dev \ - libsdl2-mixer-dev \ - libsdl2-ttf-dev \ - libpython3.6-dev \ - libpython3.7-dev \ - libzbar-dev \ lsb-release \ make \ - pkg-config \ - python3.6 \ - python3.6-dev \ - python3.7 \ - python3.7-dev \ - sudo \ - tox \ - virtualenv + sudo # prepare non root env RUN useradd --create-home --shell /bin/bash ${USER} # with sudo access and no password RUN usermod -append --groups sudo ${USER} RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers +# gives access to video so the camera can be accessed within the container +RUN gpasswd --add ${USER} video USER ${USER} WORKDIR ${WORK_DIR} COPY . ${WORK_DIR} -RUN make +RUN sudo make system_dependencies && make virtualenv ENTRYPOINT ["./dockerfiles/start.sh"] diff --git a/dockerfiles/env.list b/dockerfiles/env.list new file mode 100644 index 0000000..732d46e --- /dev/null +++ b/dockerfiles/env.list @@ -0,0 +1,9 @@ +# used by coveralls.io, refs: +# https://coveralls-python.readthedocs.io/en/latest/usage/tox.html#travisci +CI +TRAVIS +TRAVIS_BRANCH +TRAVIS_JOB_ID +TRAVIS_PULL_REQUEST +# used for running UI tests +DISPLAY diff --git a/requirements.txt b/requirements.txt index 7d837a9..e355c8b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ --r requirements/requirements.txt +-r requirements/requirements-base.txt -r requirements/requirements-documentation.txt --r requirements/test_requirements.txt +-r requirements/requirements-test.txt diff --git a/requirements/requirements.txt b/requirements/requirements-base.txt similarity index 84% rename from requirements/requirements.txt rename to requirements/requirements-base.txt index 4fcf674..63affbd 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements-base.txt @@ -4,4 +4,4 @@ numpy==1.16.1 opencv-python==4.1.1.26 Pillow==5.2.0 pyzbar==0.1.8 -xcamera +xcamera==2019.928 diff --git a/requirements/requirements-documentation.txt b/requirements/requirements-documentation.txt index b5cb07a..3f3273a 100644 --- a/requirements/requirements-documentation.txt +++ b/requirements/requirements-documentation.txt @@ -1 +1,3 @@ m2r==0.2.1 +Sphinx +sphinx-rtd-theme diff --git a/requirements/requirements-test.txt b/requirements/requirements-test.txt index f1943ca..09ff3bd 100644 --- a/requirements/requirements-test.txt +++ b/requirements/requirements-test.txt @@ -1,4 +1,5 @@ -isort==4.2.5 -flake8==3.3.0 -mock==2.0.0 -pytest==4.3.0 +coveralls +flake8 +isort +pytest +pytest-cov diff --git a/setup.py b/setup.py index b11d386..72dcb95 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ def read(fname): 'opencv-python>=4', 'pillow', 'pyzbar', - 'xcamera', + 'xcamera>=2019.928', ], } diff --git a/src/kivy_garden/zbarcam/__init__.py b/src/kivy_garden/zbarcam/__init__.py index f10f37a..7fe813a 100644 --- a/src/kivy_garden/zbarcam/__init__.py +++ b/src/kivy_garden/zbarcam/__init__.py @@ -7,7 +7,6 @@ """ import os - project_dir = os.path.abspath( os.path.join(__file__, os.pardir, os.pardir, os.pardir, os.pardir)) using_pip = os.path.basename(project_dir).startswith('pip-') diff --git a/src/kivy_garden/zbarcam/utils.py b/src/kivy_garden/zbarcam/utils.py index 3164f18..f1f6a53 100644 --- a/src/kivy_garden/zbarcam/utils.py +++ b/src/kivy_garden/zbarcam/utils.py @@ -10,29 +10,6 @@ def is_ios(): return platform == 'ios' -def check_camera_permission(): - """ - Android runtime `CAMERA` permission check. - """ - if not is_android(): - return True - from android.permissions import Permission, check_permission - permission = Permission.CAMERA - return check_permission(permission) - - -def check_request_camera_permission(callback=None): - """ - Android runtime `CAMERA` permission check & request. - """ - had_permission = check_camera_permission() - if not had_permission: - from android.permissions import Permission, request_permissions - permissions = [Permission.CAMERA] - request_permissions(permissions, callback) - return had_permission - - def fix_android_image(pil_image): """ On Android, the image seems mirrored and rotated somehow, refs #32. diff --git a/src/kivy_garden/zbarcam/version.py b/src/kivy_garden/zbarcam/version.py index 1e8ec57..ec34387 100644 --- a/src/kivy_garden/zbarcam/version.py +++ b/src/kivy_garden/zbarcam/version.py @@ -1,7 +1,7 @@ -__version__ = '2019.0910' +__version__ = '2019.1020' # The `__version_code__` is used for the F-Droid auto update and should match # the `versionCode` from the `build.gradle` file located in: -# `.buildozer/android/platform/build/dists/zbarcamdemo/` +# `.buildozer/android/platform/build-*/dists/zbarcamdemo__*/build.gradle` # The auto update method used is the `HTTP`, see: # https://f-droid.org/en/docs/Build_Metadata_Reference/#UpdateCheckMode -__version_code__ = 721202810 +__version_code__ = 721202920 diff --git a/src/kivy_garden/zbarcam/zbarcam.kv b/src/kivy_garden/zbarcam/zbarcam.kv index 80a5d6e..2a077ff 100644 --- a/src/kivy_garden/zbarcam/zbarcam.kv +++ b/src/kivy_garden/zbarcam/zbarcam.kv @@ -1,10 +1,11 @@ +#:import XCamera kivy_garden.xcamera.XCamera #:import is_android kivy_garden.zbarcam.utils.is_android : Widget: # invert width/height on rotated Android # https://stackoverflow.com/a/45192295/185510 id: proxy - CustomXCamera: + XCamera: id: xcamera play: True resolution: root.resolution diff --git a/src/kivy_garden/zbarcam/zbarcam.py b/src/kivy_garden/zbarcam/zbarcam.py index a138dde..1d85e7e 100644 --- a/src/kivy_garden/zbarcam/zbarcam.py +++ b/src/kivy_garden/zbarcam/zbarcam.py @@ -2,57 +2,17 @@ from collections import namedtuple import PIL -from kivy.clock import Clock, mainthread +from kivy.clock import Clock from kivy.lang import Builder from kivy.properties import ListProperty from kivy.uix.anchorlayout import AnchorLayout -from kivy_garden.xcamera import XCamera from pyzbar import pyzbar -from .utils import check_request_camera_permission, fix_android_image +from .utils import fix_android_image MODULE_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) -class CustomXCamera(XCamera): - """ - Inherits from `kivy_garden.xcamera.XCamera`. - Overrides `_on_index()` to make sure the `kivy.core.camera.Camera` object - is only created if permission are granted on Android. - On other system, it's a noop calling the parent `_on_index()`. - """ - - def __init__(self, **kwargs): - self.register_event_type('on_camera_ready') - super().__init__(**kwargs) - - def _on_index(self, *largs): - """ - Overrides `kivy.uix.camera.Camera._on_index()` to make sure - `camera.open()` is not called unless Android `CAMERA` permission is - granted, refs #12. - """ - @mainthread - def on_permissions_callback(permissions, grant_results): - """ - On camera permission callback calls parent `_on_index()` method. - """ - if all(grant_results): - self._on_index_dispatch(*largs) - if check_request_camera_permission(callback=on_permissions_callback): - self._on_index_dispatch(*largs) - - def _on_index_dispatch(self, *largs): - super()._on_index(*largs) - self.dispatch('on_camera_ready') - - def on_camera_ready(self): - """ - Fired when the camera is ready. - """ - pass - - class ZBarCam(AnchorLayout): """ Widget that use the Camera and zbar to detect qrcode. diff --git a/src/main.py b/src/main.py index ab19071..6db2c13 100755 --- a/src/main.py +++ b/src/main.py @@ -9,7 +9,6 @@ from kivy.app import App from kivy.lang import Builder - DEMO_APP_KV_LANG = """ #:import ZBarCam kivy_garden.zbarcam.ZBarCam #:import ZBarSymbol pyzbar.pyzbar.ZBarSymbol diff --git a/tests/test_zbarcam.py b/tests/kivy_garden/zbarcam/test_zbarcam.py similarity index 72% rename from tests/test_zbarcam.py rename to tests/kivy_garden/zbarcam/test_zbarcam.py index 0c4b035..2c7370b 100644 --- a/tests/test_zbarcam.py +++ b/tests/kivy_garden/zbarcam/test_zbarcam.py @@ -1,14 +1,17 @@ import os import unittest +from unittest import mock -import mock from kivy.base import EventLoop from kivy.core.image import Image from kivy_garden.zbarcam import ZBarCam FIXTURE_DIR = os.path.join( - os.path.dirname(os.path.abspath(__file__)), 'fixtures') -# https://github.com/kivy/kivy/blob/1.10.1/doc/sources/faq.rst + os.path.abspath( + os.path.join(__file__, os.pardir, os.pardir, os.pardir, 'fixtures') + ) +) +# https://github.com/kivy/kivy/blob/1.11.1/doc/sources/faq.rst EventLoop.ensure_window() @@ -26,7 +29,7 @@ def test_detect_qrcode_frame_no_qrcode(self): texture = Image(fixture_path).texture code_types = self.zbarcam.code_types symbols = self.zbarcam._detect_qrcode_frame(texture, code_types) - self.assertEqual(symbols, []) + assert symbols == [] def test_detect_qrcode_frame_one_qrcode(self): """ @@ -36,9 +39,9 @@ def test_detect_qrcode_frame_one_qrcode(self): texture = Image(fixture_path).texture code_types = self.zbarcam.code_types symbols = self.zbarcam._detect_qrcode_frame(texture, code_types) - self.assertEqual( - symbols, - [ZBarCam.Symbol(type='QRCODE', data=b'zbarlight test qr code')]) + assert symbols == [ + ZBarCam.Symbol(type='QRCODE', data=b'zbarlight test qr code') + ] def test_detect_qrcode_frame_one_qrcode_one_ean(self): """ @@ -48,12 +51,10 @@ def test_detect_qrcode_frame_one_qrcode_one_ean(self): texture = Image(fixture_path).texture code_types = self.zbarcam.code_types symbols = self.zbarcam._detect_qrcode_frame(texture, code_types) - self.assertEqual( - symbols, [ - ZBarCam.Symbol(type='QRCODE', data=b'zbarlight test qr code'), - ZBarCam.Symbol(type='UPCA', data=b'012345678905') - ] - ) + assert symbols == [ + ZBarCam.Symbol(type='QRCODE', data=b'zbarlight test qr code'), + ZBarCam.Symbol(type='UPCA', data=b'012345678905') + ] def test_detect_qrcode_frame_two_qrcodes(self): """ @@ -64,9 +65,7 @@ def test_detect_qrcode_frame_two_qrcodes(self): code_types = self.zbarcam.code_types symbols = self.zbarcam._detect_qrcode_frame(texture, code_types) Symbol = ZBarCam.Symbol - self.assertEqual( - symbols, [ - Symbol(type='QRCODE', data=b'second zbarlight test qr code'), - Symbol(type='QRCODE', data=b'zbarlight test qr code'), - ] - ) + assert symbols == [ + Symbol(type='QRCODE', data=b'second zbarlight test qr code'), + Symbol(type='QRCODE', data=b'zbarlight test qr code'), + ] diff --git a/tests/ui/README.md b/tests/ui/README.md deleted file mode 100644 index 0d43cdb..0000000 --- a/tests/ui/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# README - -User interface tests. Tests are built on top of [KeyWeeUsr/KivyUnitTest](https://github.com/KeyWeeUsr/KivyUnitTest). diff --git a/tests/ui/__init__.py b/tests/ui/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/ui/test_zbarcam_ui.py b/tests/ui/test_zbarcam_ui.py deleted file mode 100644 index 8016b0d..0000000 --- a/tests/ui/test_zbarcam_ui.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -import time -import unittest -from functools import partial - -import mock -from kivy.clock import Clock -from kivy_garden.zbarcam.zbarcam import ZBarCam - -from main import DemoApp - - -class UITestCase(unittest.TestCase): - - # sleep function that catches `dt` from Clock - def pause(*args): - time.sleep(0.000001) - - def advance_frames(self, count): - """ - Borrowed from Kivy 1.10.0+ /kivy/tests/common.py - GraphicUnitTest.advance_frames() - Makes it possible to to wait for UI to process, refs #110. - """ - from kivy.base import EventLoop - for i in range(count): - EventLoop.idle() - - @staticmethod - def get_camera_class(): - """ - Continuous integration providers don't have a camera available. - """ - if os.environ.get('CI', False): - Camera = None - else: - from kivy.core.camera import Camera - return Camera - - def helper_test_open_application(self, app): - """ - Makes sure the ZBarCam widget is rendered, hence the application - started without crashing. - """ - self.assertEqual(app.root.ids.zbarcam.__class__, ZBarCam) - - # main test function - def run_test(self, app, *args): - Clock.schedule_interval(self.pause, 0.000001) - # lets it finish to init - self.advance_frames(1) - self.helper_test_open_application(app) - # Comment out if you are editing the test, it'll leave the - # Window opened. - app.stop() - - # same named function as the filename(!) - def test_ui_base(self): - # uses the `wraps` parameter to conditionally enable/disable mock - Camera = self.get_camera_class() - with mock.patch('kivy.uix.camera.CoreCamera', wraps=Camera): - app = DemoApp() - p = partial(self.run_test, app) - Clock.schedule_once(p, 0.000001) - app.run() - - -if __name__ == '__main__': - unittest.main() diff --git a/tox.ini b/tox.ini index d6b1741..1b218a0 100644 --- a/tox.ini +++ b/tox.ini @@ -2,29 +2,17 @@ envlist = pep8,isort-check,py36,py37 # no setup.py to be ran skipsdist = True -# trick to enable pre-installation of Cython -# https://stackoverflow.com/a/50081741/185510 -indexserver = - preinstall = https://pypi.python.org/simple [testenv] setenv = - KIVY_UNITTEST = 1 PYTHONPATH = {toxinidir}/src/ + SOURCES = src/ tests/ setup.py setup_meta.py passenv = DISPLAY -deps = - :preinstall: Cython==0.28.6 - -r{toxinidir}/requirements/requirements.txt - -r{toxinidir}/requirements/requirements-test.txt -commands = pytest --ignore tests/ui/ tests/ +deps = -r{toxinidir}/requirements.txt +commands = pytest --cov src/ tests/ [testenv:pep8] -deps = - -r{toxinidir}/requirements/requirements-test.txt -commands = flake8 src/ tests/ setup.py setup_meta.py +commands = flake8 {env:SOURCES} [testenv:isort-check] -deps = - -r{toxinidir}/requirements/requirements-test.txt -commands = - isort --check-only --recursive --diff src/ tests/ setup.py setup_meta.py +commands = isort --check-only --recursive --diff {env:SOURCES}