From 53a6542ac53edcc84997e90aa0cd5e87fa757c7b Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Wed, 23 Dec 2020 23:14:33 +0000 Subject: [PATCH 01/10] Add webtest dependency --- poetry.lock | 51 ++++++++++++++++++++++++++++++++++++++++++++------ pyproject.toml | 1 + 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index b5612f7..62ca2c2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -612,7 +612,7 @@ twitter = ["twython"] [[package]] name = "notebook" -version = "6.1.5" +version = "6.1.6" description = "A web-based notebook environment for interactive computing" category = "dev" optional = false @@ -635,8 +635,9 @@ tornado = ">=5.0" traitlets = ">=4.2.1" [package.extras] -docs = ["sphinx", "nbsphinx", "sphinxcontrib-github-alt"] -test = ["nose", "coverage", "requests", "nose-warnings-filters", "nbval", "nose-exclude", "selenium", "pytest", "pytest-cov", "requests-unixsocket"] +docs = ["sphinx", "nbsphinx", "sphinxcontrib-github-alt", "sphinx-rtd-theme"] +json-logging = ["json-logging"] +test = ["pytest", "coverage", "requests", "nbval", "selenium", "pytest-cov", "requests-unixsocket"] [[package]] name = "orjson" @@ -1001,6 +1002,18 @@ brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +[[package]] +name = "waitress" +version = "1.4.4" +description = "Waitress WSGI server" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.extras] +docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"] +testing = ["pytest", "pytest-cover", "coverage (>=5.0)"] + [[package]] name = "wcwidth" version = "0.2.5" @@ -1029,6 +1042,24 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"] testing = ["pytest (>=3.1.0)", "coverage", "pytest-cov", "pytest-xdist"] +[[package]] +name = "webtest" +version = "2.0.35" +description = "Helper to test WSGI applications" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +beautifulsoup4 = "*" +six = "*" +waitress = ">=0.8.5" +WebOb = ">=1.2" + +[package.extras] +docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.8)"] +tests = ["nose (<1.3.0)", "coverage", "mock", "pastedeploy", "wsgiproxy2", "pyquery"] + [[package]] name = "widgetsnbextension" version = "3.5.1" @@ -1043,7 +1074,7 @@ notebook = ">=4.4.1" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "4652673e61d57bf6f9a67c42f717aa0d014e0073a274183a8d47e65e0c251ffa" +content-hash = "6672edcfd7abe5be006c66fefed7f00b286aa8233a28c0b2f5d42b5328d7f0d8" [metadata.files] anki = [ @@ -1305,8 +1336,8 @@ nltk = [ {file = "nltk-3.5.zip", hash = "sha256:845365449cd8c5f9731f7cb9f8bd6fd0767553b9d53af9eb1b3abf7700936b35"}, ] notebook = [ - {file = "notebook-6.1.5-py3-none-any.whl", hash = "sha256:508cf9dad7cdb3188f1aa27017dc78179029dfe83814fc505329f689bc2ab50f"}, - {file = "notebook-6.1.5.tar.gz", hash = "sha256:3db37ae834c5f3b6378381229d0e5dfcbfb558d08c8ce646b1ad355147f5e91d"}, + {file = "notebook-6.1.6-py3-none-any.whl", hash = "sha256:e6a62188e319a5d45dd2ed24719f646adf88bef8be1f654ebd0ab360ece6d7a6"}, + {file = "notebook-6.1.6.tar.gz", hash = "sha256:cf40d4f81541401db5a2fda1707ca7877157abd41f04ef7b88f02b67f3c61791"}, ] orjson = [ {file = "orjson-3.4.6-cp36-cp36m-macosx_10_7_x86_64.whl", hash = "sha256:4e258f4696255de8038fd01ead8277a7c5c6d1e453cc7ca5aad8c1e9f74af62e"}, @@ -1645,6 +1676,10 @@ urllib3 = [ {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"}, {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, ] +waitress = [ + {file = "waitress-1.4.4-py2.py3-none-any.whl", hash = "sha256:3d633e78149eb83b60a07dfabb35579c29aac2d24bb803c18b26fb2ab1a584db"}, + {file = "waitress-1.4.4.tar.gz", hash = "sha256:1bb436508a7487ac6cb097ae7a7fe5413aefca610550baf58f0940e51ecfb261"}, +] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, @@ -1657,6 +1692,10 @@ webob = [ {file = "WebOb-1.8.6-py2.py3-none-any.whl", hash = "sha256:a3c89a8e9ba0aeb17382836cdb73c516d0ecf6630ec40ec28288f3ed459ce87b"}, {file = "WebOb-1.8.6.tar.gz", hash = "sha256:aa3a917ed752ba3e0b242234b2a373f9c4e2a75d35291dcbe977649bd21fd108"}, ] +webtest = [ + {file = "WebTest-2.0.35-py2.py3-none-any.whl", hash = "sha256:44ddfe99b5eca4cf07675e7222c81dd624d22f9a26035d2b93dc8862dc1153c6"}, + {file = "WebTest-2.0.35.tar.gz", hash = "sha256:aac168b5b2b4f200af4e35867cf316712210e3d5db81c1cbdff38722647bb087"}, +] widgetsnbextension = [ {file = "widgetsnbextension-3.5.1-py2.py3-none-any.whl", hash = "sha256:bd314f8ceb488571a5ffea6cc5b9fc6cba0adaf88a9d2386b93a489751938bcd"}, {file = "widgetsnbextension-3.5.1.tar.gz", hash = "sha256:079f87d87270bce047512400efd70238820751a11d2d8cb137a5a5bdbaf255c7"}, diff --git a/pyproject.toml b/pyproject.toml index 418a362..47816bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ webob = "^1.8.6" mkdocs = "^1.1.2" jupyter = "^1.0.0" jupyterlab = "^2.2.2" +webtest = "^2.0.35" [build-system] requires = ["poetry>=0.12"] From 692f9a004cfc44ef26bb6961ef42cd333156070f Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Wed, 23 Dec 2020 23:22:16 +0000 Subject: [PATCH 02/10] Add init command to download dependencies using poetry --- Makefile | 6 +++++- config/.env.example | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 40533d6..fea27e8 100644 --- a/Makefile +++ b/Makefile @@ -23,4 +23,8 @@ notebooks: %: @test -f scripts/${*}.sh - @${SHELL} scripts/${*}.sh \ No newline at end of file + @${SHELL} scripts/${*}.sh + +.PHONY: init #: Download Python dependencies. +init: + @${POETRY} install \ No newline at end of file diff --git a/config/.env.example b/config/.env.example index 65979ac..b254545 100644 --- a/config/.env.example +++ b/config/.env.example @@ -1,6 +1,7 @@ # .env.example (anki-sync-server) ## Make +POETRY=poetry MKDOCS=mkdocs JUPYTER=jupyter From 0fe4b4f8b642e529d6e054b92a70c54d176933ca Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Wed, 23 Dec 2020 23:24:07 +0000 Subject: [PATCH 03/10] Add tests command to run unittests --- Makefile | 4 ++++ config/.env.example | 1 + 2 files changed, 5 insertions(+) diff --git a/Makefile b/Makefile index fea27e8..4bdcb67 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,10 @@ help: docs: print-env @${MKDOCS} ${MKDOCS_OPTION} -f docs/mkdocs.yml +.PHONY: tests #: Run unit tests. +tests: + @${UNITTEST} discover -s tests + .PHONY: notebooks #: Run jupyter notebooks. notebooks: @${JUPYTER} ${JUPYTER_OPTION} diff --git a/config/.env.example b/config/.env.example index b254545..9a8d79a 100644 --- a/config/.env.example +++ b/config/.env.example @@ -4,6 +4,7 @@ POETRY=poetry MKDOCS=mkdocs JUPYTER=jupyter +UNITTEST=python -m unittest ## Ankisyncd ANKISYNCD_HOST=0.0.0.0 From 2e820b0a89f899f720826cd2aac983d295e07dea Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Wed, 23 Dec 2020 23:24:31 +0000 Subject: [PATCH 04/10] Add ankisyncd package to pass tests --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 47816bd..484036a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,9 @@ name = "anki-sync-server" version = "2.2.0" description = "Self-hosted Anki Sync Server." authors = ["Vikash Kothary "] +packages = [ + { include = "ankisyncd", from = "src" } +] [tool.poetry.dependencies] python = "^3.8" From d3ec4e44f2b955f1af907e7870dff048fa1b1953 Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Wed, 23 Dec 2020 23:27:21 +0000 Subject: [PATCH 05/10] Move line break around ENV variable in Makefile for aesthetic reasons --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4bdcb67..80d063e 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,8 @@ ANKI_SERVER_NAME ?= "Anki Sync Server" ANKI_SERVER_VERSION ?= "v0.1.0" ANKI_SERVER_DESCRIPTION ?= "Self-hosted Anki Sync Server." -ENV ?= local +ENV ?= local -include config/.env.${ENV} export From b0a62702d9a549ce65fd5816e1f5857f488694ac Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Wed, 23 Dec 2020 23:30:56 +0000 Subject: [PATCH 06/10] Run lock script to update requirements.txt files with webtest dependency --- src/requirements-dev.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/requirements-dev.txt b/src/requirements-dev.txt index 007ad7c..8942b4b 100644 --- a/src/requirements-dev.txt +++ b/src/requirements-dev.txt @@ -47,7 +47,7 @@ nbconvert==6.0.7; python_version >= "3.6" nbformat==5.0.8; python_version >= "3.6" nest-asyncio==1.4.3; python_version >= "3.6" nltk==3.5; python_version >= "3.5" -notebook==6.1.5; python_version >= "3.5" +notebook==6.1.6; python_version >= "3.5" orjson==3.4.6; python_version >= "3.8" packaging==20.8; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" pandocfilters==1.4.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" @@ -84,8 +84,10 @@ tornado==6.1; python_version >= "3.6" tqdm==4.54.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0" traitlets==5.0.5; python_version >= "3.7" urllib3==1.26.2; python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.8" +waitress==1.4.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" wcwidth==0.2.5; python_full_version >= "3.6.1" and python_version >= "3.6" webencodings==0.5.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" webob==1.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") +webtest==2.0.35 widgetsnbextension==3.5.1 -e src/. From e210f7b3fab2c4e1f8393cf10d904d25a18c9f9b Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Wed, 23 Dec 2020 23:36:40 +0000 Subject: [PATCH 07/10] Fix PATH variable to autodetect dependencies in project virtualenv --- config/.env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/.env.example b/config/.env.example index 9a8d79a..a2d1fe1 100644 --- a/config/.env.example +++ b/config/.env.example @@ -27,4 +27,4 @@ MKDOCS_OPTION=serve JUPYTER_OPTION=lab ## Path -PATH:=.venv/bin/path:${PATH} \ No newline at end of file +PATH:=.venv/bin:${PATH} \ No newline at end of file From a48c974b6a460ac7676a16e3f20ebacca9d82182 Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Sun, 27 Dec 2020 17:52:47 +0000 Subject: [PATCH 08/10] Comment out optional ANKISYNCD variables --- config/.env.example | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/.env.example b/config/.env.example index a2d1fe1..64c96c3 100644 --- a/config/.env.example +++ b/config/.env.example @@ -15,10 +15,10 @@ ANKISYNCD_BASE_MEDIA_URL=/msync/ ANKISYNCD_AUTH_DB_PATH=./auth.db ANKISYNCD_SESSION_DB_PATH=./session.db -ANKISYNCD_FULL_SYNC_MANAGER -ANKISYNCD_SESSION_MANAGER -ANKISYNCD_USER_MANAGER -ANKISYNCD_COLLECTION_WRAPPER +# ANKISYNCD_FULL_SYNC_MANAGER +# ANKISYNCD_SESSION_MANAGER +# ANKISYNCD_USER_MANAGER +# ANKISYNCD_COLLECTION_WRAPPER ## Mkdocs MKDOCS_OPTION=serve From 4667c85e00f8a96acbcbef2a66e9efb6be2eebe6 Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Sun, 27 Dec 2020 17:54:59 +0000 Subject: [PATCH 09/10] Use poetry to run python dependences --- config/.env.example | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/.env.example b/config/.env.example index 64c96c3..35de7e1 100644 --- a/config/.env.example +++ b/config/.env.example @@ -2,9 +2,9 @@ ## Make POETRY=poetry -MKDOCS=mkdocs -JUPYTER=jupyter -UNITTEST=python -m unittest +MKDOCS=poetry run mkdocs +JUPYTER=poetry run jupyter +UNITTEST=poetry run python -m unittest ## Ankisyncd ANKISYNCD_HOST=0.0.0.0 From f73e3d5f8c5e05ebeb5ee504b60eafb28f6447d0 Mon Sep 17 00:00:00 2001 From: Vikash Kothary Date: Sun, 27 Dec 2020 18:11:20 +0000 Subject: [PATCH 10/10] Add documentation on how to run tests --- README.md | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 88334b7..d0c9e05 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,11 @@ It supports Python 3 and Anki 2.1. - [Installing](#installing) - [Installing (Docker)](#installing-docker) - [Setting up Anki](#setting-up-anki) - - [Anki 2.1](#anki-21) - - [Anki 2.0](#anki-20) - - [AnkiDroid](#ankidroid) + - [Anki 2.1](#anki-21) + - [Anki 2.0](#anki-20) + - [AnkiDroid](#ankidroid) + - [Development](#development) + - [Testing](#testing) - [ENVVAR configuration overrides](#envvar-configuration-overrides) - [Support for other database backends](#support-for-other-database-backends) @@ -142,6 +144,35 @@ Even though the AnkiDroid interface will request an email address, this is not required; it will simply be the username you configured with `ankisyncctl.py adduser`. +Development +----------- + +### Testing + +0. Prerequites + +This project uses [GNU Make](https://www.gnu.org/software/make/) to simplify the development commands. It also uses [Poetry](https://python-poetry.org/) to manage the Python dependencies. Ensure they are installed. + +1. Create a config for your local environment. + +```bash +$ cp config/.env.example config/.env.local +``` + +See [ENVVAR configuration overrides](#envvar-configuration-overrides) for more information. + +2. Download Python dependencies. + +```bash +$ make init +``` + +3. Run unit tests. + +```bash +$ make tests +``` + ENVVAR configuration overrides ------------------------------