Adopt mypy as a static type checker #7
|
@ -2,13 +2,20 @@
|
||||||
Article query interface
|
Article query interface
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|
||||||
from amanuensis.db import *
|
from amanuensis.db import *
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
def create(db: DbContext, lexicon_id: int, user_id: int, character_id: int) -> Article:
|
def create(
|
||||||
|
db: DbContext,
|
||||||
|
lexicon_id: int,
|
||||||
|
user_id: int,
|
||||||
|
character_id: Optional[int],
|
||||||
|
) -> Article:
|
||||||
"""
|
"""
|
||||||
Create a new article in a lexicon.
|
Create a new article in a lexicon.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
Character query interface
|
Character query interface
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from sqlalchemy import select, func
|
from sqlalchemy import select, func
|
||||||
|
|
||||||
from amanuensis.db import *
|
from amanuensis.db import *
|
||||||
|
@ -9,7 +11,11 @@ from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
def create(
|
def create(
|
||||||
db: DbContext, lexicon_id: int, user_id: int, name: str, signature: str
|
db: DbContext,
|
||||||
|
lexicon_id: int,
|
||||||
|
user_id: int,
|
||||||
|
name: str,
|
||||||
|
signature: Optional[str],
|
||||||
) -> Character:
|
) -> Character:
|
||||||
"""
|
"""
|
||||||
Create a new character for a user.
|
Create a new character for a user.
|
||||||
|
|
|
@ -13,7 +13,12 @@ from amanuensis.errors import ArgumentError
|
||||||
RE_ALPHANUM_DASH_UNDER = re.compile(r"^[A-Za-z0-9-_]*$")
|
RE_ALPHANUM_DASH_UNDER = re.compile(r"^[A-Za-z0-9-_]*$")
|
||||||
|
|
||||||
|
|
||||||
def create(db: DbContext, name: str, title: str, prompt: str) -> Lexicon:
|
def create(
|
||||||
|
db: DbContext,
|
||||||
|
name: str,
|
||||||
|
title: str,
|
||||||
|
prompt: str,
|
||||||
|
) -> Lexicon:
|
||||||
"""
|
"""
|
||||||
Create a new lexicon.
|
Create a new lexicon.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -8,7 +8,12 @@ from amanuensis.db import DbContext, Membership
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
def create(db: DbContext, user_id: int, lexicon_id: int, is_editor: bool) -> Membership:
|
def create(
|
||||||
|
db: DbContext,
|
||||||
|
user_id: int,
|
||||||
|
lexicon_id: int,
|
||||||
|
is_editor: bool,
|
||||||
|
) -> Membership:
|
||||||
"""
|
"""
|
||||||
Create a new user membership in a lexicon.
|
Create a new user membership in a lexicon.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -10,7 +10,12 @@ from amanuensis.db import DbContext, Post
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
def create(db: DbContext, lexicon_id: int, user_id: int, body: str) -> Post:
|
def create(
|
||||||
|
db: DbContext,
|
||||||
|
lexicon_id: int,
|
||||||
|
user_id: int,
|
||||||
|
body: str,
|
||||||
|
) -> Post:
|
||||||
"""
|
"""
|
||||||
Create a new post
|
Create a new post
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[mypy]
|
||||||
|
ignore_missing_imports = true
|
||||||
|
exclude = "amanuensis/cli/.*|amanuensis/config/.*|amanuensis/lexicon/.*|amanuensis/log/.*|amanuensis/models/.*|amanuensis/parser/.*|amanuensis/resources/.*|amanuensis/server/.*|amanuensis/user/.*|amanuensis/__main__.py"
|
||||||
|
; mypy stable doesn't support pyproject.toml yet
|
|
@ -158,6 +158,22 @@ category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mypy"
|
||||||
|
version = "0.812"
|
||||||
|
description = "Optional static typing for Python"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.5"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
mypy-extensions = ">=0.4.3,<0.5.0"
|
||||||
|
typed-ast = ">=1.4.0,<1.5.0"
|
||||||
|
typing-extensions = ">=3.7.4"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dmypy = ["psutil (>=4.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy-extensions"
|
name = "mypy-extensions"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -281,6 +297,22 @@ category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typed-ast"
|
||||||
|
version = "1.4.3"
|
||||||
|
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "3.10.0.0"
|
||||||
|
description = "Backported and Experimental Type Hints for Python 3.5+"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wcwidth"
|
name = "wcwidth"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
|
@ -320,7 +352,7 @@ locale = ["Babel (>=1.3)"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.8"
|
python-versions = "^3.8"
|
||||||
content-hash = "e81ba4ffeb172410ef80bd6500c0af4e3be6b800d9cfda85df2f6a5c74319d87"
|
content-hash = "8c38b0703447e638ee8181a4e449f0eab57858e171cd0de9d4e9fe07c61d0071"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
appdirs = [
|
appdirs = [
|
||||||
|
@ -458,6 +490,30 @@ more-itertools = [
|
||||||
{file = "more-itertools-8.8.0.tar.gz", hash = "sha256:83f0308e05477c68f56ea3a888172c78ed5d5b3c282addb67508e7ba6c8f813a"},
|
{file = "more-itertools-8.8.0.tar.gz", hash = "sha256:83f0308e05477c68f56ea3a888172c78ed5d5b3c282addb67508e7ba6c8f813a"},
|
||||||
{file = "more_itertools-8.8.0-py3-none-any.whl", hash = "sha256:2cf89ec599962f2ddc4d568a05defc40e0a587fbc10d5989713638864c36be4d"},
|
{file = "more_itertools-8.8.0-py3-none-any.whl", hash = "sha256:2cf89ec599962f2ddc4d568a05defc40e0a587fbc10d5989713638864c36be4d"},
|
||||||
]
|
]
|
||||||
|
mypy = [
|
||||||
|
{file = "mypy-0.812-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a26f8ec704e5a7423c8824d425086705e381b4f1dfdef6e3a1edab7ba174ec49"},
|
||||||
|
{file = "mypy-0.812-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:28fb5479c494b1bab244620685e2eb3c3f988d71fd5d64cc753195e8ed53df7c"},
|
||||||
|
{file = "mypy-0.812-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:9743c91088d396c1a5a3c9978354b61b0382b4e3c440ce83cf77994a43e8c521"},
|
||||||
|
{file = "mypy-0.812-cp35-cp35m-win_amd64.whl", hash = "sha256:d7da2e1d5f558c37d6e8c1246f1aec1e7349e4913d8fb3cb289a35de573fe2eb"},
|
||||||
|
{file = "mypy-0.812-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4eec37370483331d13514c3f55f446fc5248d6373e7029a29ecb7b7494851e7a"},
|
||||||
|
{file = "mypy-0.812-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d65cc1df038ef55a99e617431f0553cd77763869eebdf9042403e16089fe746c"},
|
||||||
|
{file = "mypy-0.812-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:61a3d5b97955422964be6b3baf05ff2ce7f26f52c85dd88db11d5e03e146a3a6"},
|
||||||
|
{file = "mypy-0.812-cp36-cp36m-win_amd64.whl", hash = "sha256:25adde9b862f8f9aac9d2d11971f226bd4c8fbaa89fb76bdadb267ef22d10064"},
|
||||||
|
{file = "mypy-0.812-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:552a815579aa1e995f39fd05dde6cd378e191b063f031f2acfe73ce9fb7f9e56"},
|
||||||
|
{file = "mypy-0.812-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:499c798053cdebcaa916eef8cd733e5584b5909f789de856b482cd7d069bdad8"},
|
||||||
|
{file = "mypy-0.812-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:5873888fff1c7cf5b71efbe80e0e73153fe9212fafdf8e44adfe4c20ec9f82d7"},
|
||||||
|
{file = "mypy-0.812-cp37-cp37m-win_amd64.whl", hash = "sha256:9f94aac67a2045ec719ffe6111df543bac7874cee01f41928f6969756e030564"},
|
||||||
|
{file = "mypy-0.812-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d23e0ea196702d918b60c8288561e722bf437d82cb7ef2edcd98cfa38905d506"},
|
||||||
|
{file = "mypy-0.812-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:674e822aa665b9fd75130c6c5f5ed9564a38c6cea6a6432ce47eafb68ee578c5"},
|
||||||
|
{file = "mypy-0.812-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:abf7e0c3cf117c44d9285cc6128856106183938c68fd4944763003decdcfeb66"},
|
||||||
|
{file = "mypy-0.812-cp38-cp38-win_amd64.whl", hash = "sha256:0d0a87c0e7e3a9becdfbe936c981d32e5ee0ccda3e0f07e1ef2c3d1a817cf73e"},
|
||||||
|
{file = "mypy-0.812-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7ce3175801d0ae5fdfa79b4f0cfed08807af4d075b402b7e294e6aa72af9aa2a"},
|
||||||
|
{file = "mypy-0.812-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b09669bcda124e83708f34a94606e01b614fa71931d356c1f1a5297ba11f110a"},
|
||||||
|
{file = "mypy-0.812-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:33f159443db0829d16f0a8d83d94df3109bb6dd801975fe86bacb9bf71628e97"},
|
||||||
|
{file = "mypy-0.812-cp39-cp39-win_amd64.whl", hash = "sha256:3f2aca7f68580dc2508289c729bd49ee929a436208d2b2b6aab15745a70a57df"},
|
||||||
|
{file = "mypy-0.812-py3-none-any.whl", hash = "sha256:2f9b3407c58347a452fc0736861593e105139b905cca7d097e413453a1d650b4"},
|
||||||
|
{file = "mypy-0.812.tar.gz", hash = "sha256:cd07039aa5df222037005b08fbbfd69b3ab0b0bd7a07d7906de75ae52c4e3119"},
|
||||||
|
]
|
||||||
mypy-extensions = [
|
mypy-extensions = [
|
||||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||||
|
@ -565,6 +621,43 @@ toml = [
|
||||||
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||||
]
|
]
|
||||||
|
typed-ast = [
|
||||||
|
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"},
|
||||||
|
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"},
|
||||||
|
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"},
|
||||||
|
{file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"},
|
||||||
|
{file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"},
|
||||||
|
{file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"},
|
||||||
|
{file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"},
|
||||||
|
{file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"},
|
||||||
|
{file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"},
|
||||||
|
{file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"},
|
||||||
|
{file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"},
|
||||||
|
{file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"},
|
||||||
|
{file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"},
|
||||||
|
{file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"},
|
||||||
|
{file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"},
|
||||||
|
{file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"},
|
||||||
|
{file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"},
|
||||||
|
{file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"},
|
||||||
|
{file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"},
|
||||||
|
{file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"},
|
||||||
|
{file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"},
|
||||||
|
{file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"},
|
||||||
|
{file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"},
|
||||||
|
{file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"},
|
||||||
|
{file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"},
|
||||||
|
{file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"},
|
||||||
|
{file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"},
|
||||||
|
{file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"},
|
||||||
|
{file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"},
|
||||||
|
{file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"},
|
||||||
|
]
|
||||||
|
typing-extensions = [
|
||||||
|
{file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"},
|
||||||
|
{file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"},
|
||||||
|
{file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"},
|
||||||
|
]
|
||||||
wcwidth = [
|
wcwidth = [
|
||||||
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
||||||
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
|
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
|
||||||
|
|
|
@ -14,20 +14,14 @@ SQLAlchemy = "^1.4.12"
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
pytest = "^5.2"
|
pytest = "^5.2"
|
||||||
black = "^21.5b2"
|
black = "^21.5b2"
|
||||||
|
mypy = "^0.812"
|
||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
extend-exclude = '''
|
extend-exclude = "^/amanuensis/cli/.*|^/amanuensis/config/.*|^/amanuensis/lexicon/.*|^/amanuensis/log/.*|^/amanuensis/models/.*|^/amanuensis/parser/.*|^/amanuensis/resources/.*|^/amanuensis/server/.*|^/amanuensis/user/.*|^/amanuensis/__main__.py"
|
||||||
^/amanuensis/cli/.*|
|
|
||||||
^/amanuensis/config/.*|
|
[tool.mypy]
|
||||||
^/amanuensis/lexicon/.*|
|
ignore_missing_imports = true
|
||||||
^/amanuensis/log/.*|
|
exclude = "amanuensis/cli/.*|amanuensis/config/.*|amanuensis/lexicon/.*|amanuensis/log/.*|amanuensis/models/.*|amanuensis/parser/.*|amanuensis/resources/.*|amanuensis/server/.*|amanuensis/user/.*|amanuensis/__main__.py"
|
||||||
^/amanuensis/models/.*|
|
|
||||||
^/amanuensis/parser/.*|
|
|
||||||
^/amanuensis/resources/.*|
|
|
||||||
^/amanuensis/server/.*|
|
|
||||||
^/amanuensis/user/.*|
|
|
||||||
^/amanuensis/__main__.py
|
|
||||||
'''
|
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
addopts = "--show-capture=log"
|
addopts = "--show-capture=log"
|
||||||
|
|
|
@ -11,7 +11,7 @@ import amanuensis.backend.user as userq
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def db():
|
def db() -> DbContext:
|
||||||
"""Provides an initialized database in memory."""
|
"""Provides an initialized database in memory."""
|
||||||
db = DbContext("sqlite:///:memory:", debug=False)
|
db = DbContext("sqlite:///:memory:", debug=False)
|
||||||
db.create_all()
|
db.create_all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from amanuensis.db import DbContext
|
from amanuensis.db import DbContext
|
||||||
|
from amanuensis.db.models import Character, Lexicon, User
|
||||||
import amanuensis.backend.article as artiq
|
import amanuensis.backend.article as artiq
|
||||||
|
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
@ -9,18 +10,18 @@ from amanuensis.errors import ArgumentError
|
||||||
def test_create_article(db: DbContext, make):
|
def test_create_article(db: DbContext, make):
|
||||||
"""Test new article creation"""
|
"""Test new article creation"""
|
||||||
# Create two users in a shared lexicon
|
# Create two users in a shared lexicon
|
||||||
user1 = make.user()
|
user1: User = make.user()
|
||||||
user2 = make.user()
|
user2: User = make.user()
|
||||||
lexicon1 = make.lexicon()
|
lexicon1: Lexicon = make.lexicon()
|
||||||
make.membership(user_id=user1.id, lexicon_id=lexicon1.id)
|
make.membership(user_id=user1.id, lexicon_id=lexicon1.id)
|
||||||
make.membership(user_id=user2.id, lexicon_id=lexicon1.id)
|
make.membership(user_id=user2.id, lexicon_id=lexicon1.id)
|
||||||
char1_1 = make.character(lexicon_id=lexicon1.id, user_id=user1.id)
|
char1_1: Character = make.character(lexicon_id=lexicon1.id, user_id=user1.id)
|
||||||
char1_2 = make.character(lexicon_id=lexicon1.id, user_id=user2.id)
|
char1_2: Character = make.character(lexicon_id=lexicon1.id, user_id=user2.id)
|
||||||
|
|
||||||
# Create a lexicon that only one user is in
|
# Create a lexicon that only one user is in
|
||||||
lexicon2 = make.lexicon()
|
lexicon2: Lexicon = make.lexicon()
|
||||||
make.membership(user_id=user2.id, lexicon_id=lexicon2.id)
|
make.membership(user_id=user2.id, lexicon_id=lexicon2.id)
|
||||||
char2_2 = make.character(lexicon_id=lexicon2.id, user_id=user2.id)
|
char2_2: Character = make.character(lexicon_id=lexicon2.id, user_id=user2.id)
|
||||||
|
|
||||||
# User cannot create article for another user's character
|
# User cannot create article for another user's character
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
|
|
|
@ -7,35 +7,44 @@ from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
def test_create_character(db: DbContext, lexicon_with_editor, make):
|
def test_create_character(db: DbContext, lexicon_with_editor, make):
|
||||||
"""Test creating a character."""
|
"""Test creating a character."""
|
||||||
|
lexicon: Lexicon
|
||||||
|
user: User
|
||||||
lexicon, user = lexicon_with_editor
|
lexicon, user = lexicon_with_editor
|
||||||
kwargs = {
|
defaults: dict = {
|
||||||
"db": db,
|
"db": db,
|
||||||
"user_id": user.id,
|
"user_id": user.id,
|
||||||
"lexicon_id": lexicon.id,
|
"lexicon_id": lexicon.id,
|
||||||
"name": "Character Name",
|
"name": "Character Name",
|
||||||
"signature": "Signature",
|
"signature": "Signature",
|
||||||
}
|
}
|
||||||
|
kwargs: dict
|
||||||
|
|
||||||
# Bad argument types
|
# Bad argument types
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
charq.create(**{**kwargs, "name": b"bytestring"})
|
kwargs = {**defaults, "name": b"bytestring"}
|
||||||
|
charq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
charq.create(**{**kwargs, "name": None})
|
kwargs = {**defaults, "name": None}
|
||||||
|
charq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
charq.create(**{**kwargs, "signature": b"bytestring"})
|
kwargs = {**defaults, "signature": b"bytestring"}
|
||||||
|
charq.create(**kwargs)
|
||||||
|
|
||||||
# Bad character name
|
# Bad character name
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
charq.create(**{**kwargs, "name": " "})
|
kwargs = {**defaults, "name": " "}
|
||||||
|
charq.create(**kwargs)
|
||||||
|
|
||||||
# Signature is auto-populated
|
# Signature is auto-populated
|
||||||
char = charq.create(**{**kwargs, "signature": None})
|
kwargs = {**defaults, "signature": None}
|
||||||
|
char = charq.create(**kwargs)
|
||||||
assert char.signature is not None
|
assert char.signature is not None
|
||||||
|
|
||||||
# User must be in lexicon
|
# User must be in lexicon
|
||||||
new_user = make.user()
|
new_user: User = make.user()
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
charq.create(**{**kwargs, "user_id": new_user.id})
|
kwargs = {**defaults, "user_id": new_user.id}
|
||||||
|
charq.create(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
def test_character_limits(db: DbContext, lexicon_with_editor):
|
def test_character_limits(db: DbContext, lexicon_with_editor):
|
||||||
|
@ -47,12 +56,14 @@ def test_character_limits(db: DbContext, lexicon_with_editor):
|
||||||
# Set character limit to one and create a character
|
# Set character limit to one and create a character
|
||||||
lexicon.character_limit = 1
|
lexicon.character_limit = 1
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
char1 = charq.create(db, lexicon.id, user.id, "Test Character 1", signature=None)
|
char1: Character = charq.create(
|
||||||
|
db, lexicon.id, user.id, "Test Character 1", signature=None
|
||||||
|
)
|
||||||
assert char1.id, "Failed to create character 1"
|
assert char1.id, "Failed to create character 1"
|
||||||
|
|
||||||
# Creating a second character should fail
|
# Creating a second character should fail
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
char2 = charq.create(
|
char2: Character = charq.create(
|
||||||
db, lexicon.id, user.id, "Test Character 2", signature=None
|
db, lexicon.id, user.id, "Test Character 2", signature=None
|
||||||
)
|
)
|
||||||
assert char2
|
assert char2
|
||||||
|
@ -65,7 +76,7 @@ def test_character_limits(db: DbContext, lexicon_with_editor):
|
||||||
|
|
||||||
# Creating a third character should fail
|
# Creating a third character should fail
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
char3 = charq.create(
|
char3: Character = charq.create(
|
||||||
db, lexicon.id, user.id, "Test Character 3", signature=None
|
db, lexicon.id, user.id, "Test Character 3", signature=None
|
||||||
)
|
)
|
||||||
assert char3
|
assert char3
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from amanuensis.db.models import Lexicon
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -9,24 +10,37 @@ from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
def test_create_lexicon(db: DbContext):
|
def test_create_lexicon(db: DbContext):
|
||||||
"""Test new game creation."""
|
"""Test new game creation."""
|
||||||
kwargs = {"name": "Test", "title": None, "prompt": "A test Lexicon game"}
|
defaults: dict = {
|
||||||
|
"db": db,
|
||||||
|
"name": "Test",
|
||||||
|
"title": None,
|
||||||
|
"prompt": "A test Lexicon game",
|
||||||
|
}
|
||||||
|
kwargs: dict
|
||||||
|
|
||||||
# Test name constraints
|
# Test name constraints
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
lexiq.create(db, **{**kwargs, "name": None})
|
kwargs = {**defaults, "name": None}
|
||||||
|
lexiq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
lexiq.create(db, **{**kwargs, "name": ""})
|
kwargs = {**defaults, "name": ""}
|
||||||
|
lexiq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
lexiq.create(db, **{**kwargs, "name": " "})
|
kwargs = {**defaults, "name": " "}
|
||||||
|
lexiq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
lexiq.create(db, **{**kwargs, "name": ".."})
|
kwargs = {**defaults, "name": ".."}
|
||||||
|
lexiq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
lexiq.create(db, **{**kwargs, "name": "\x00"})
|
kwargs = {**defaults, "name": "\x00"}
|
||||||
|
lexiq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
lexiq.create(db, **{**kwargs, "name": "space in name"})
|
kwargs = {**defaults, "name": "space in name"}
|
||||||
|
lexiq.create(**kwargs)
|
||||||
|
|
||||||
# Validate that creation populates fields, including timestamps
|
# Validate that creation populates fields, including timestamps
|
||||||
before = datetime.datetime.utcnow() - datetime.timedelta(seconds=1)
|
before = datetime.datetime.utcnow() - datetime.timedelta(seconds=1)
|
||||||
new_lexicon = lexiq.create(db, **kwargs)
|
new_lexicon: Lexicon = lexiq.create(**defaults)
|
||||||
after = datetime.datetime.utcnow() + datetime.timedelta(seconds=1)
|
after = datetime.datetime.utcnow() + datetime.timedelta(seconds=1)
|
||||||
assert new_lexicon
|
assert new_lexicon
|
||||||
assert new_lexicon.id is not None
|
assert new_lexicon.id is not None
|
||||||
|
@ -36,5 +50,4 @@ def test_create_lexicon(db: DbContext):
|
||||||
|
|
||||||
# No duplicate lexicon names
|
# No duplicate lexicon names
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
duplicate = lexiq.create(db, **kwargs)
|
lexiq.create(**defaults)
|
||||||
assert duplicate
|
|
||||||
|
|
|
@ -10,13 +10,13 @@ import amanuensis.backend.membership as memq
|
||||||
def test_create_membership(db: DbContext, make):
|
def test_create_membership(db: DbContext, make):
|
||||||
"""Test joining a game."""
|
"""Test joining a game."""
|
||||||
# Set up a user and a lexicon
|
# Set up a user and a lexicon
|
||||||
new_user = make.user()
|
new_user: User = make.user()
|
||||||
assert new_user.id, "Failed to create user"
|
assert new_user.id, "Failed to create user"
|
||||||
new_lexicon = make.lexicon()
|
new_lexicon: Lexicon = make.lexicon()
|
||||||
assert new_lexicon.id, "Failed to create lexicon"
|
assert new_lexicon.id, "Failed to create lexicon"
|
||||||
|
|
||||||
# Add the user to the lexicon as an editor
|
# Add the user to the lexicon as an editor
|
||||||
mem = memq.create(db, new_user.id, new_lexicon.id, True)
|
mem: Membership = memq.create(db, new_user.id, new_lexicon.id, True)
|
||||||
assert mem, "Failed to create membership"
|
assert mem, "Failed to create membership"
|
||||||
|
|
||||||
# Check that the user and lexicon are mutually visible in the ORM relationships
|
# Check that the user and lexicon are mutually visible in the ORM relationships
|
||||||
|
@ -24,7 +24,7 @@ def test_create_membership(db: DbContext, make):
|
||||||
assert any(map(lambda mem: mem.user == new_user, new_lexicon.memberships))
|
assert any(map(lambda mem: mem.user == new_user, new_lexicon.memberships))
|
||||||
|
|
||||||
# Check that the editor flag was set properly
|
# Check that the editor flag was set properly
|
||||||
editor = db(
|
editor: User = db(
|
||||||
select(User)
|
select(User)
|
||||||
.join(User.memberships)
|
.join(User.memberships)
|
||||||
.join(Membership.lexicon)
|
.join(Membership.lexicon)
|
||||||
|
@ -37,5 +37,4 @@ def test_create_membership(db: DbContext, make):
|
||||||
|
|
||||||
# Check that joining twice is not allowed
|
# Check that joining twice is not allowed
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
mem2 = memq.create(db, new_user.id, new_lexicon.id, False)
|
memq.create(db, new_user.id, new_lexicon.id, False)
|
||||||
assert mem2
|
|
||||||
|
|
|
@ -11,34 +11,47 @@ def test_create_post(db: DbContext, lexicon_with_editor):
|
||||||
lexicon, editor = lexicon_with_editor
|
lexicon, editor = lexicon_with_editor
|
||||||
|
|
||||||
# argument dictionary for post object
|
# argument dictionary for post object
|
||||||
kwargs = {"lexicon_id": lexicon.id, "user_id": editor.id, "body": "body"}
|
defaults: dict = {
|
||||||
|
"db": db,
|
||||||
|
"lexicon_id": lexicon.id,
|
||||||
|
"user_id": editor.id,
|
||||||
|
"body": "body",
|
||||||
|
}
|
||||||
|
kwargs: dict
|
||||||
|
|
||||||
# ids are integers
|
# ids are integers
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
postq.create(db, **{**kwargs, "user_id": "zero"})
|
kwargs = {**defaults, "user_id": "zero"}
|
||||||
|
postq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
postq.create(db, **{**kwargs, "lexicon_id": "zero"})
|
kwargs = {**defaults, "lexicon_id": "zero"}
|
||||||
|
postq.create(**kwargs)
|
||||||
|
|
||||||
# empty arguments don't work
|
# empty arguments don't work
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
postq.create(db, **{**kwargs, "lexicon_id": ""})
|
kwargs = {**defaults, "lexicon_id": ""}
|
||||||
|
postq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
postq.create(db, **{**kwargs, "user_id": ""})
|
kwargs = {**defaults, "user_id": ""}
|
||||||
|
postq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
postq.create(db, **{**kwargs, "body": ""})
|
kwargs = {**defaults, "body": ""}
|
||||||
|
postq.create(**kwargs)
|
||||||
|
|
||||||
# post with only whitespace doesn't work
|
# post with only whitespace doesn't work
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
postq.create(db, **{**kwargs, "body": " "})
|
kwargs = {**defaults, "body": " "}
|
||||||
|
postq.create(**kwargs)
|
||||||
|
|
||||||
# post creation works and populates fields
|
# post creation works and populates fields
|
||||||
new_post = postq.create(db, **kwargs)
|
new_post = postq.create(**defaults)
|
||||||
assert new_post
|
assert new_post
|
||||||
assert new_post.lexicon_id is not None
|
assert new_post.lexicon_id is not None
|
||||||
assert new_post.user_id is not None
|
assert new_post.user_id is not None
|
||||||
assert new_post.body is not None
|
assert new_post.body is not None
|
||||||
|
|
||||||
# post creation works when user is None
|
# post creation works when user is None
|
||||||
new_post = postq.create(db, **{**kwargs, "user_id": None})
|
kwargs = {**defaults, "user_id": None}
|
||||||
|
new_post = postq.create(**kwargs)
|
||||||
assert new_post
|
assert new_post
|
||||||
assert new_post.user_id is None
|
assert new_post.user_id is None
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from amanuensis.db.models import User
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from amanuensis.db import DbContext
|
from amanuensis.db import DbContext
|
||||||
|
@ -7,39 +8,45 @@ from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
def test_create_user(db: DbContext):
|
def test_create_user(db: DbContext):
|
||||||
"""Test new user creation."""
|
"""Test new user creation."""
|
||||||
kwargs = {
|
defaults: dict = {
|
||||||
|
"db": db,
|
||||||
"username": "username",
|
"username": "username",
|
||||||
"password": "password",
|
"password": "password",
|
||||||
"display_name": "User Name",
|
"display_name": "User Name",
|
||||||
"email": "user@example.com",
|
"email": "user@example.com",
|
||||||
"is_site_admin": False,
|
"is_site_admin": False,
|
||||||
}
|
}
|
||||||
|
kwargs: dict
|
||||||
|
|
||||||
# Test length constraints
|
# Test length constraints
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
userq.create(db, **{**kwargs, "username": "me"})
|
kwargs = {**defaults, "username": "me"}
|
||||||
|
userq.create(**kwargs)
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
userq.create(
|
kwargs = {**defaults, "username": "the right honorable user-name, esquire"}
|
||||||
db, **{**kwargs, "username": "the right honorable user-name, esquire"}
|
userq.create(**kwargs)
|
||||||
)
|
|
||||||
# Test allowed characters
|
# Test allowed characters
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
userq.create(db, **{**kwargs, "username": "user name"})
|
kwargs = {**defaults, "username": "user name"}
|
||||||
|
userq.create(**kwargs)
|
||||||
|
|
||||||
# No password
|
# No password
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
userq.create(db, **{**kwargs, "password": None})
|
kwargs = {**defaults, "password": None}
|
||||||
|
userq.create(**kwargs)
|
||||||
|
|
||||||
# Valid creation works and populates fields
|
# Valid creation works and populates fields
|
||||||
new_user = userq.create(db, **kwargs)
|
new_user = userq.create(**defaults)
|
||||||
assert new_user
|
assert new_user
|
||||||
assert new_user.id is not None
|
assert new_user.id is not None
|
||||||
assert new_user.created is not None
|
assert new_user.created is not None
|
||||||
|
|
||||||
# No duplicate usernames
|
# No duplicate usernames
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
duplicate = userq.create(db, **kwargs)
|
userq.create(**defaults)
|
||||||
|
|
||||||
# Missing display name populates with username
|
# Missing display name populates with username
|
||||||
user2_kw = {**kwargs, "username": "user2", "display_name": None}
|
user2_kw: dict = {**defaults, "username": "user2", "display_name": None}
|
||||||
user2 = userq.create(db, **user2_kw)
|
user2: User = userq.create(**user2_kw)
|
||||||
assert user2.display_name is not None
|
assert user2.display_name is not None
|
||||||
|
|
Loading…
Reference in New Issue