From f99411f2f96620ae9683482c769f3d4f39083c8d Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 3 Jul 2021 14:52:27 -0700 Subject: [PATCH] move some files around because pytest is being weird --- Makefile | 10 +- poetry.lock | 114 +++--- tests/{ => bdd}/features/build.feature | 0 tests/{ => bdd}/features/core.feature | 0 tests/{ => bdd}/features/datetime.feature | 0 tests/{ => bdd}/features/delete.feature | 0 tests/{ => bdd}/features/encrypt.feature | 0 tests/{ => bdd}/features/file_storage.feature | 0 tests/{ => bdd}/features/format.feature | 0 tests/{ => bdd}/features/import.feature | 0 .../features/multiple_journals.feature | 0 tests/{ => bdd}/features/password.feature | 0 tests/{ => bdd}/features/search.feature | 0 tests/{ => bdd}/features/star.feature | 0 tests/{ => bdd}/features/tag.feature | 0 tests/{ => bdd}/features/upgrade.feature | 0 tests/{ => bdd}/features/write.feature | 0 tests/bdd/test_features.py | 17 + tests/{step_defs => }/conftest.py | 8 +- tests/step_defs/__init__.py | 3 - tests/step_defs/fixtures.py | 201 ----------- tests/step_defs/given_steps.py | 134 ------- tests/step_defs/helpers.py | 40 --- tests/step_defs/test_features.py | 17 - tests/step_defs/then_steps.py | 331 ------------------ tests/step_defs/when_steps.py | 113 ------ 26 files changed, 81 insertions(+), 907 deletions(-) rename tests/{ => bdd}/features/build.feature (100%) rename tests/{ => bdd}/features/core.feature (100%) rename tests/{ => bdd}/features/datetime.feature (100%) rename tests/{ => bdd}/features/delete.feature (100%) rename tests/{ => bdd}/features/encrypt.feature (100%) rename tests/{ => bdd}/features/file_storage.feature (100%) rename tests/{ => bdd}/features/format.feature (100%) rename tests/{ => bdd}/features/import.feature (100%) rename tests/{ => bdd}/features/multiple_journals.feature (100%) rename tests/{ => bdd}/features/password.feature (100%) rename tests/{ => bdd}/features/search.feature (100%) rename tests/{ => bdd}/features/star.feature (100%) rename tests/{ => bdd}/features/tag.feature (100%) rename tests/{ => bdd}/features/upgrade.feature (100%) rename tests/{ => bdd}/features/write.feature (100%) create mode 100644 tests/bdd/test_features.py rename tests/{step_defs => }/conftest.py (81%) delete mode 100644 tests/step_defs/__init__.py delete mode 100644 tests/step_defs/fixtures.py delete mode 100644 tests/step_defs/given_steps.py delete mode 100644 tests/step_defs/helpers.py delete mode 100644 tests/step_defs/test_features.py delete mode 100644 tests/step_defs/then_steps.py delete mode 100644 tests/step_defs/when_steps.py diff --git a/Makefile b/Makefile index a04a9c86..a4494ee3 100644 --- a/Makefile +++ b/Makefile @@ -24,13 +24,13 @@ lint: ## Check style with various tools unit: # unit tests poetry run pytest tests/unit -e2e: # end-to-end tests - poetry run pytest tests/step_defs --gherkin-terminal-reporter --tb=native --diff-type=unified +bdd: # bdd tests + poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native --diff-type=unified -e2e-debug: # end-to-end tests - poetry run pytest tests/step_defs --gherkin-terminal-reporter --tb=native --diff-type=unified -x -vv +bdd-debug: # bdd tests + poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native --diff-type=unified -x -vv -test: lint unit e2e ## Run unit tests and behave tests +test: lint unit bdd ## Run unit tests and behave tests build: poetry build diff --git a/poetry.lock b/poetry.lock index 50b41e3c..2d1a8ea2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -214,7 +214,7 @@ python-versions = "*" [[package]] name = "importlib-metadata" -version = "4.5.0" +version = "4.6.0" description = "Read metadata from Python packages" category = "main" optional = false @@ -226,7 +226,8 @@ zipp = ">=0.5" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +perf = ["ipython"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -444,11 +445,11 @@ python-versions = "*" [[package]] name = "packaging" -version = "20.9" +version = "21.0" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2" @@ -641,11 +642,11 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm [[package]] name = "pytest-bdd" -version = "4.0.2" +version = "4.1.0" description = "BDD for pytest" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [package.dependencies] glob2 = "*" @@ -654,7 +655,6 @@ parse = "*" parse-type = "*" py = "*" pytest = ">=4.3" -six = ">=1.9.0" [[package]] name = "pytest-clarity" @@ -724,7 +724,7 @@ pyyaml = "*" [[package]] name = "regex" -version = "2021.4.4" +version = "2021.7.1" description = "Alternative regular expression module, to replace re." category = "dev" optional = false @@ -861,7 +861,7 @@ test = ["coverage", "flake8", "wheel"] [[package]] name = "zipp" -version = "3.4.1" +version = "3.5.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false @@ -869,7 +869,7 @@ python-versions = ">=3.6" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] lock-version = "1.1" @@ -992,8 +992,8 @@ glob2 = [ {file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.5.0-py3-none-any.whl", hash = "sha256:833b26fb89d5de469b24a390e9df088d4e52e4ba33b01dc5e0e4f41b81a16c00"}, - {file = "importlib_metadata-4.5.0.tar.gz", hash = "sha256:b142cc1dd1342f31ff04bb7d022492b09920cb64fed867cd3ea6f80fe3ebd139"}, + {file = "importlib_metadata-4.6.0-py3-none-any.whl", hash = "sha256:c6513572926a96458f8c8f725bf0e00108fba0c9583ade9bd15b869c9d726e33"}, + {file = "importlib_metadata-4.6.0.tar.gz", hash = "sha256:4a5611fea3768d3d967c447ab4e93f567d95db92225b43b7b238dbfb855d70bb"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -1090,8 +1090,8 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] packaging = [ - {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, - {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, + {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, + {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, ] parse = [ {file = "parse-1.19.0.tar.gz", hash = "sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b"}, @@ -1165,8 +1165,8 @@ pytest = [ {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"}, ] pytest-bdd = [ - {file = "pytest-bdd-4.0.2.tar.gz", hash = "sha256:982489f2f036c7561affe4eeb5b392a37e1ace2a9f260cad747b1c8119e63cfd"}, - {file = "pytest_bdd-4.0.2-py2.py3-none-any.whl", hash = "sha256:74ea5a147ea558c99ae83d838e6acbe5c9e6843884a958f8231615d96838733d"}, + {file = "pytest-bdd-4.1.0.tar.gz", hash = "sha256:304cd2b09923b838d0c2f08331d1f4236a14ef3594efa94e3bdae0f384d3fa5d"}, + {file = "pytest_bdd-4.1.0-py3-none-any.whl", hash = "sha256:7c5221680cec9a97630e1fae6132f4a97c2f86a90914206ee06a55ae1a409fe5"}, ] pytest-clarity = [ {file = "pytest-clarity-0.3.0a0.tar.gz", hash = "sha256:5cc99e3d9b7969dfe17e5f6072d45a917c59d363b679686d3c958a1ded2e4dcf"}, @@ -1215,47 +1215,43 @@ pyyaml-env-tag = [ {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] regex = [ - {file = "regex-2021.4.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7"}, - {file = "regex-2021.4.4-cp36-cp36m-win32.whl", hash = "sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29"}, - {file = "regex-2021.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79"}, - {file = "regex-2021.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439"}, - {file = "regex-2021.4.4-cp37-cp37m-win32.whl", hash = "sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d"}, - {file = "regex-2021.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3"}, - {file = "regex-2021.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87"}, - {file = "regex-2021.4.4-cp38-cp38-win32.whl", hash = "sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac"}, - {file = "regex-2021.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2"}, - {file = "regex-2021.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042"}, - {file = "regex-2021.4.4-cp39-cp39-win32.whl", hash = "sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6"}, - {file = "regex-2021.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07"}, - {file = "regex-2021.4.4.tar.gz", hash = "sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb"}, + {file = "regex-2021.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:494d0172774dc0beeea984b94c95389143db029575f7ca908edd74469321ea99"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:8cf6728f89b071bd3ab37cb8a0e306f4de897553a0ed07442015ee65fbf53d62"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1806370b2bef4d4193eebe8ee59a9fd7547836a34917b7badbe6561a8594d9cb"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d0cf2651a8804f6325747c7e55e3be0f90ee2848e25d6b817aa2728d263f9abb"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:268fe9dd1deb4a30c8593cabd63f7a241dfdc5bd9dd0233906c718db22cdd49a"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:7743798dfb573d006f1143d745bf17efad39775a5190b347da5d83079646be56"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:0e46c1191b2eb293a6912269ed08b4512e7e241bbf591f97e527492e04c77e93"}, + {file = "regex-2021.7.1-cp36-cp36m-win32.whl", hash = "sha256:b1dbeef938281f240347d50f28ae53c4b046a23389cd1fc4acec5ea0eae646a1"}, + {file = "regex-2021.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6c72ebb72e64e9bd195cb35a9b9bbfb955fd953b295255b8ae3e4ad4a146b615"}, + {file = "regex-2021.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf819c5b77ff44accc9a24e31f1f7ceaaf6c960816913ed3ef8443b9d20d81b6"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e80d2851109e56420b71f9702ad1646e2f0364528adbf6af85527bc61e49f394"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a1b6a3f600d6aff97e3f28c34192c9ed93fee293bd96ef327b64adb51a74b2f6"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ed77b97896312bc2deafe137ca2626e8b63808f5bedb944f73665c68093688a7"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a548bb51c4476332ce4139df8e637386730f79a92652a907d12c696b6252b64d"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:210c359e6ee5b83f7d8c529ba3c75ba405481d50f35a420609b0db827e2e3bb5"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:1d386402ae7f3c9b107ae5863f7ecccb0167762c82a687ae6526b040feaa5ac6"}, + {file = "regex-2021.7.1-cp37-cp37m-win32.whl", hash = "sha256:5049d00dbb78f9d166d1c704e93934d42cce0570842bb1a61695123d6b01de09"}, + {file = "regex-2021.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:361be4d311ac995a8c7ad577025a3ae3a538531b1f2cf32efd8b7e5d33a13e5a"}, + {file = "regex-2021.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f32f47fb22c988c0b35756024b61d156e5c4011cb8004aa53d93b03323c45657"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b024ee43ee6b310fad5acaee23e6485b21468718cb792a9d1693eecacc3f0b7e"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:b092754c06852e8a8b022004aff56c24b06310189186805800d09313c37ce1f8"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a8a5826d8a1b64e2ff9af488cc179e1a4d0f144d11ce486a9f34ea38ccedf4ef"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:444723ebaeb7fa8125f29c01a31101a3854ac3de293e317944022ae5effa53a4"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:fdad3122b69cdabdb3da4c2a4107875913ac78dab0117fc73f988ad589c66b66"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:4b1999ef60c45357598935c12508abf56edbbb9c380df6f336de38a6c3a294ae"}, + {file = "regex-2021.7.1-cp38-cp38-win32.whl", hash = "sha256:e07e92935040c67f49571779d115ecb3e727016d42fb36ee0d8757db4ca12ee0"}, + {file = "regex-2021.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:6b8b629f93246e507287ee07e26744beaffb4c56ed520576deac8b615bd76012"}, + {file = "regex-2021.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56bef6b414949e2c9acf96cb5d78de8b529c7b99752619494e78dc76f99fd005"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:78a2a885345a2d60b5e68099e877757d5ed12e46ba1e87507175f14f80892af3"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3f7a92e60930f8fca2623d9e326c173b7cf2c8b7e4fdcf984b75a1d2fb08114d"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4fc86b729ab88fe8ac3ec92287df253c64aa71560d76da5acd8a2e245839c629"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:59845101de68fd5d3a1145df9ea022e85ecd1b49300ea68307ad4302320f6f61"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:ce269e903b00d1ab4746793e9c50a57eec5d5388681abef074d7b9a65748fca5"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:c11f2fca544b5e30a0e813023196a63b1cb9869106ef9a26e9dae28bce3e4e26"}, + {file = "regex-2021.7.1-cp39-cp39-win32.whl", hash = "sha256:1ccbd41dbee3a31e18938096510b7d4ee53aa9fce2ee3dcc8ec82ae264f6acfd"}, + {file = "regex-2021.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:18040755606b0c21281493ec309214bd61e41a170509e5014f41d6a5a586e161"}, + {file = "regex-2021.7.1.tar.gz", hash = "sha256:849802379a660206277675aa5a5c327f5c910c690649535863ddf329b0ba8c87"}, ] secretstorage = [ {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, @@ -1357,6 +1353,6 @@ yq = [ {file = "yq-2.12.2.tar.gz", hash = "sha256:2f156d0724b61487ac8752ed4eaa702a5737b804d5afa46fa55866951cd106d2"}, ] zipp = [ - {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"}, - {file = "zipp-3.4.1.tar.gz", hash = "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76"}, + {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"}, + {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"}, ] diff --git a/tests/features/build.feature b/tests/bdd/features/build.feature similarity index 100% rename from tests/features/build.feature rename to tests/bdd/features/build.feature diff --git a/tests/features/core.feature b/tests/bdd/features/core.feature similarity index 100% rename from tests/features/core.feature rename to tests/bdd/features/core.feature diff --git a/tests/features/datetime.feature b/tests/bdd/features/datetime.feature similarity index 100% rename from tests/features/datetime.feature rename to tests/bdd/features/datetime.feature diff --git a/tests/features/delete.feature b/tests/bdd/features/delete.feature similarity index 100% rename from tests/features/delete.feature rename to tests/bdd/features/delete.feature diff --git a/tests/features/encrypt.feature b/tests/bdd/features/encrypt.feature similarity index 100% rename from tests/features/encrypt.feature rename to tests/bdd/features/encrypt.feature diff --git a/tests/features/file_storage.feature b/tests/bdd/features/file_storage.feature similarity index 100% rename from tests/features/file_storage.feature rename to tests/bdd/features/file_storage.feature diff --git a/tests/features/format.feature b/tests/bdd/features/format.feature similarity index 100% rename from tests/features/format.feature rename to tests/bdd/features/format.feature diff --git a/tests/features/import.feature b/tests/bdd/features/import.feature similarity index 100% rename from tests/features/import.feature rename to tests/bdd/features/import.feature diff --git a/tests/features/multiple_journals.feature b/tests/bdd/features/multiple_journals.feature similarity index 100% rename from tests/features/multiple_journals.feature rename to tests/bdd/features/multiple_journals.feature diff --git a/tests/features/password.feature b/tests/bdd/features/password.feature similarity index 100% rename from tests/features/password.feature rename to tests/bdd/features/password.feature diff --git a/tests/features/search.feature b/tests/bdd/features/search.feature similarity index 100% rename from tests/features/search.feature rename to tests/bdd/features/search.feature diff --git a/tests/features/star.feature b/tests/bdd/features/star.feature similarity index 100% rename from tests/features/star.feature rename to tests/bdd/features/star.feature diff --git a/tests/features/tag.feature b/tests/bdd/features/tag.feature similarity index 100% rename from tests/features/tag.feature rename to tests/bdd/features/tag.feature diff --git a/tests/features/upgrade.feature b/tests/bdd/features/upgrade.feature similarity index 100% rename from tests/features/upgrade.feature rename to tests/bdd/features/upgrade.feature diff --git a/tests/features/write.feature b/tests/bdd/features/write.feature similarity index 100% rename from tests/features/write.feature rename to tests/bdd/features/write.feature diff --git a/tests/bdd/test_features.py b/tests/bdd/test_features.py new file mode 100644 index 00000000..b824df39 --- /dev/null +++ b/tests/bdd/test_features.py @@ -0,0 +1,17 @@ +from pytest_bdd import scenarios + +scenarios("features/build.feature") +scenarios("features/core.feature") +scenarios("features/datetime.feature") +scenarios("features/delete.feature") +scenarios("features/encrypt.feature") +scenarios("features/file_storage.feature") +scenarios("features/format.feature") +scenarios("features/import.feature") +scenarios("features/multiple_journals.feature") +scenarios("features/password.feature") +scenarios("features/search.feature") +scenarios("features/star.feature") +scenarios("features/tag.feature") +scenarios("features/upgrade.feature") +scenarios("features/write.feature") diff --git a/tests/step_defs/conftest.py b/tests/conftest.py similarity index 81% rename from tests/step_defs/conftest.py rename to tests/conftest.py index a3021972..277e2602 100644 --- a/tests/step_defs/conftest.py +++ b/tests/conftest.py @@ -7,10 +7,10 @@ from jrnl.os_compat import on_windows pytest_plugins = [ - "tests.step_defs.fixtures", - "tests.step_defs.given_steps", - "tests.step_defs.when_steps", - "tests.step_defs.then_steps", + "tests.lib.fixtures", + "tests.lib.given_steps", + "tests.lib.when_steps", + "tests.lib.then_steps", ] diff --git a/tests/step_defs/__init__.py b/tests/step_defs/__init__.py deleted file mode 100644 index 46468510..00000000 --- a/tests/step_defs/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -import sys - -sys.path.append("..") diff --git a/tests/step_defs/fixtures.py b/tests/step_defs/fixtures.py deleted file mode 100644 index a93a7e43..00000000 --- a/tests/step_defs/fixtures.py +++ /dev/null @@ -1,201 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -from collections import defaultdict -import os -from pathlib import Path -import tempfile - -from keyring import backend -from keyring import errors -from keyring import set_keyring -from pytest import fixture -import toml - -from jrnl.config import load_config - - -# --- Keyring --- # -@fixture -def keyring(): - set_keyring(NoKeyring()) - - -@fixture -def keyring_type(): - return "default" - - -class TestKeyring(backend.KeyringBackend): - """A test keyring that just stores its values in a hash""" - - priority = 1 - keys = defaultdict(dict) - - def set_password(self, servicename, username, password): - self.keys[servicename][username] = password - - def get_password(self, servicename, username): - return self.keys[servicename].get(username) - - def delete_password(self, servicename, username): - self.keys[servicename][username] = None - - -class NoKeyring(backend.KeyringBackend): - """A keyring that simulated an environment with no keyring backend.""" - - priority = 2 - keys = defaultdict(dict) - - def set_password(self, servicename, username, password): - raise errors.NoKeyringError - - def get_password(self, servicename, username): - raise errors.NoKeyringError - - def delete_password(self, servicename, username): - raise errors.NoKeyringError - - -class FailedKeyring(backend.KeyringBackend): - """A keyring that cannot be retrieved.""" - - priority = 2 - - def set_password(self, servicename, username, password): - raise errors.KeyringError - - def get_password(self, servicename, username): - raise errors.KeyringError - - def delete_password(self, servicename, username): - raise errors.KeyringError - - -# ----- Misc ----- # -@fixture -def cli_run(): - return {"status": 0, "stdout": None, "stderr": None} - - -@fixture -def mocks(): - return dict() - - -@fixture -def temp_dir(): - return tempfile.TemporaryDirectory() - - -@fixture -def working_dir(request): - return os.path.join(request.config.rootpath, "tests") - - -@fixture -def config_path(temp_dir): - os.chdir(temp_dir.name) - return temp_dir.name + "/jrnl.yaml" - - -@fixture -def toml_version(working_dir): - pyproject = os.path.join(working_dir, "..", "pyproject.toml") - pyproject_contents = toml.load(pyproject) - return pyproject_contents["tool"]["poetry"]["version"] - - -@fixture -def password(): - return "" - - -@fixture -def input_method(): - return "" - - -@fixture -def cache_dir(): - return {"exists": False, "path": ""} - - -@fixture -def str_value(): - return "" - - -@fixture -def command(): - return "" - - -@fixture -def should_not(): - return False - - -@fixture -def user_input(): - return "" - - -@fixture -def config_data(config_path): - return load_config(config_path) - - -@fixture -def journal_name(): - return None - - -@fixture -def which_output_stream(): - return None - - -@fixture -def editor_input(): - return None - - -@fixture -def num_args(): - return None - - -@fixture -def parsed_output(): - return {"lang": None, "obj": None} - - -@fixture -def editor_state(): - return { - "command": "", - "intent": {"method": "r", "input": None}, - "tmpfile": {"name": None, "content": None}, - } - - -@fixture -def editor(editor_state): - def _mock_editor(editor_command): - tmpfile = editor_command[-1] - - editor_state["command"] = editor_command - editor_state["tmpfile"]["name"] = tmpfile - - Path(tmpfile).touch() - with open(tmpfile, editor_state["intent"]["method"]) as f: - # Touch the file so jrnl knows it was edited - if editor_state["intent"]["input"] is not None: - f.write(editor_state["intent"]["input"]) - - file_content = f.read() - editor_state["tmpfile"]["content"] = file_content - - return _mock_editor diff --git a/tests/step_defs/given_steps.py b/tests/step_defs/given_steps.py deleted file mode 100644 index 649d44c5..00000000 --- a/tests/step_defs/given_steps.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -from datetime import datetime -import json -import os -import random -import shutil -import string -from unittest.mock import MagicMock -from unittest.mock import patch -from xml.etree import ElementTree - -from keyring import set_keyring -from pytest_bdd import given -from pytest_bdd.parsers import parse - -from jrnl import __version__ -from jrnl.time import __get_pdt_calendar - -from .fixtures import FailedKeyring -from .fixtures import TestKeyring - - -@given(parse("we {editor_method} to the editor if opened\n{editor_input}")) -@given(parse("we {editor_method} nothing to the editor if opened")) -def we_enter_editor(editor_method, editor_input, editor_state): - file_method = editor_state["intent"]["method"] - if editor_method == "write": - file_method = "w+" - elif editor_method == "append": - file_method = "a+" - else: - assert False, f"Method '{editor_method}' not supported" - - editor_state["intent"] = {"method": file_method, "input": editor_input} - - -@given(parse('now is ""')) -@given(parse('now is "{date_str}"')) -def now_is_str(date_str, mocks): - class DatetimeMagicMock(MagicMock): - # needed because jrnl does some reflection on datetime - def __instancecheck__(self, subclass): - return isinstance(subclass, datetime) - - def mocked_now(tz=None): - now = datetime.strptime(date_str, "%Y-%m-%d %I:%M:%S %p") - - if tz: - time_zone = datetime.utcnow().astimezone().tzinfo - now = now.replace(tzinfo=time_zone) - - return now - - # jrnl uses two different classes to parse dates, so both must be mocked - datetime_mock = DatetimeMagicMock(wraps=datetime) - datetime_mock.now.side_effect = mocked_now - - pdt = __get_pdt_calendar() - calendar_mock = MagicMock(wraps=pdt) - calendar_mock.parse.side_effect = lambda date_str_input: pdt.parse( - date_str_input, mocked_now() - ) - - mocks["datetime"] = patch("datetime.datetime", new=datetime_mock) - mocks["calendar_parse"] = patch( - "jrnl.time.__get_pdt_calendar", return_value=calendar_mock - ) - - -@given("we have a keyring", target_fixture="keyring") -@given(parse("we have a {keyring_type} keyring"), target_fixture="keyring") -def we_have_type_of_keyring(keyring_type): - if keyring_type == "failed": - set_keyring(FailedKeyring()) - else: - set_keyring(TestKeyring()) - - -@given(parse('we use the config "{config_file}"'), target_fixture="config_path") -@given('we use the config ""', target_fixture="config_path") -def we_use_the_config(config_file, temp_dir, working_dir): - # Move into temp dir as cwd - os.chdir(temp_dir.name) - - # Copy the config file over - config_source = os.path.join(working_dir, "data", "configs", config_file) - config_dest = os.path.join(temp_dir.name, config_file) - shutil.copy2(config_source, config_dest) - - # @todo make this only copy some journals over - # Copy all of the journals over - journal_source = os.path.join(working_dir, "data", "journals") - journal_dest = os.path.join(temp_dir.name, "features", "journals") - shutil.copytree(journal_source, journal_dest) - - # @todo get rid of this by using default config values - # merge in version number - if config_file.endswith("yaml") and os.path.exists(config_dest): - # Add jrnl version to file for 2.x journals - with open(config_dest, "a") as cf: - cf.write("version: {}".format(__version__)) - - return config_dest - - -@given(parse('we use the password "{pw}" if prompted'), target_fixture="password") -def use_password_forever(pw): - return pw - - -@given("we create a cache directory", target_fixture="cache_dir") -def create_cache_dir(temp_dir): - random_str = "".join(random.choices(string.ascii_uppercase + string.digits, k=20)) - - dir_path = os.path.join(temp_dir.name, "cache_" + random_str) - os.mkdir(dir_path) - return {"exists": True, "path": dir_path} - - -@given(parse("we parse the output as {language_name}"), target_fixture="parsed_output") -def parse_output_as_language(cli_run, language_name): - language_name = language_name.upper() - actual_output = cli_run["stdout"] - - if language_name == "XML": - parsed_output = ElementTree.fromstring(actual_output) - elif language_name == "JSON": - parsed_output = json.loads(actual_output) - else: - assert False, f"Language name {language_name} not recognized" - - return {"lang": language_name, "obj": parsed_output} diff --git a/tests/step_defs/helpers.py b/tests/step_defs/helpers.py deleted file mode 100644 index 7d089597..00000000 --- a/tests/step_defs/helpers.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -import os - - -def does_directory_contain_files(file_list, directory_path): - if not os.path.isdir(directory_path): - return False - - for file in file_list.split("\n"): - fullpath = directory_path + "/" + file - if not os.path.isfile(fullpath): - return False - - return True - - -def parse_should_or_should_not(should_or_should_not): - if should_or_should_not == "should": - return True - elif should_or_should_not == "should not": - return False - else: - raise Exception( - "should_or_should_not valid values are 'should' or 'should not'" - ) - - -def assert_equal_tags_ignoring_order( - actual_line, expected_line, actual_content, expected_content -): - actual_tags = set(tag.strip() for tag in actual_line[len("tags: ") :].split(",")) - expected_tags = set( - tag.strip() for tag in expected_line[len("tags: ") :].split(",") - ) - assert actual_tags == expected_tags, [ - [actual_tags, expected_tags], - [expected_content, actual_content], - ] diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py deleted file mode 100644 index 4c8d5ef9..00000000 --- a/tests/step_defs/test_features.py +++ /dev/null @@ -1,17 +0,0 @@ -from pytest_bdd import scenarios - -scenarios("../features/build.feature") -scenarios("../features/core.feature") -scenarios("../features/datetime.feature") -scenarios("../features/delete.feature") -scenarios("../features/encrypt.feature") -scenarios("../features/file_storage.feature") -scenarios("../features/format.feature") -scenarios("../features/import.feature") -scenarios("../features/multiple_journals.feature") -scenarios("../features/password.feature") -scenarios("../features/search.feature") -scenarios("../features/star.feature") -scenarios("../features/tag.feature") -scenarios("../features/upgrade.feature") -scenarios("../features/write.feature") diff --git a/tests/step_defs/then_steps.py b/tests/step_defs/then_steps.py deleted file mode 100644 index b56c203f..00000000 --- a/tests/step_defs/then_steps.py +++ /dev/null @@ -1,331 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -import json -import os -import re -from xml.etree import ElementTree - -from pytest_bdd import then -from pytest_bdd.parsers import parse -import yaml - -from jrnl.config import scope_config - -from .helpers import assert_equal_tags_ignoring_order -from .helpers import does_directory_contain_files -from .helpers import parse_should_or_should_not - - -@then("we should get no error") -def should_get_no_error(cli_run): - assert cli_run["status"] == 0, cli_run["status"] - - -@then(parse('the output should match "{regex}"')) -def output_should_match(regex, cli_run): - out = cli_run["stdout"] - matches = re.findall(regex, out) - assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" - - -@then(parse("the output should contain\n{expected_output}")) -@then(parse('the output should contain "{expected_output}"')) -@then('the output should contain ""') -@then(parse("the {which_output_stream} output should contain\n{expected_output}")) -@then(parse('the {which_output_stream} output should contain "{expected_output}"')) -def output_should_contain(expected_output, which_output_stream, cli_run): - assert expected_output - if which_output_stream is None: - assert (expected_output in cli_run["stdout"]) or ( - expected_output in cli_run["stderr"] - ) - - elif which_output_stream == "standard": - assert expected_output in cli_run["stdout"] - - elif which_output_stream == "error": - assert expected_output in cli_run["stderr"] - - else: - assert expected_output in cli_run[which_output_stream] - - -@then(parse("the output should not contain\n{expected_output}")) -@then(parse('the output should not contain "{expected_output}"')) -@then('the output should not contain ""') -def output_should_not_contain(expected_output, cli_run): - assert expected_output not in cli_run["stdout"] - - -@then(parse("the output should be\n{expected_output}")) -@then(parse('the output should be "{expected_output}"')) -@then('the output should be ""') -def output_should_be(expected_output, cli_run): - actual = cli_run["stdout"].strip() - expected = expected_output.strip() - assert expected == actual - - -@then("the output should be empty") -def output_should_be_empty(cli_run): - actual = cli_run["stdout"].strip() - assert actual == "" - - -@then('the output should contain the date ""') -def output_should_contain_date(date, cli_run): - assert date and date in cli_run["stdout"] - - -@then("the output should contain pyproject.toml version") -def output_should_contain_version(cli_run, toml_version): - out = cli_run["stdout"] - assert toml_version in out, toml_version - - -@then(parse('we should see the message "{text}"')) -def should_see_the_message(text, cli_run): - out = cli_run["stderr"] - assert text in out, [text, out] - - -@then( - parse( - 'the config for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"' - ) -) -@then( - parse( - 'the config for journal "{journal_name}" {should_or_should_not} contain\n{some_yaml}' - ) -) -@then(parse('the config {should_or_should_not} contain "{some_yaml}"')) -@then(parse("the config {should_or_should_not} contain\n{some_yaml}")) -def config_var(config_data, journal_name, should_or_should_not, some_yaml): - we_should = parse_should_or_should_not(should_or_should_not) - - actual = config_data - if journal_name: - actual = actual["journals"][journal_name] - - expected = yaml.load(some_yaml, Loader=yaml.FullLoader) - - actual_slice = actual - if type(actual) is dict: - actual_slice = {key: actual.get(key, None) for key in expected.keys()} - - if we_should: - assert expected == actual_slice - else: - assert expected != actual_slice - - -@then("we should be prompted for a password") -def password_was_called(cli_run): - assert cli_run["mocks"]["getpass"].called - - -@then("we should not be prompted for a password") -def password_was_not_called(cli_run): - assert not cli_run["mocks"]["getpass"].called - - -@then(parse("the cache directory should contain the files\n{file_list}")) -def assert_dir_contains_files(file_list, cache_dir): - assert does_directory_contain_files(file_list, cache_dir["path"]) - - -@then(parse("the journal directory should contain\n{file_list}")) -def journal_directory_should_contain(config_data, file_list): - scoped_config = scope_config(config_data, "default") - - assert does_directory_contain_files(file_list, scoped_config["journal"]) - - -@then(parse('journal "{journal_name}" should not exist')) -def journal_directory_should_not_exist(config_data, journal_name): - scoped_config = scope_config(config_data, journal_name) - - assert not does_directory_contain_files( - scoped_config["journal"], "." - ), f'Journal "{journal_name}" does exist' - - -@then(parse("the journal {should_or_should_not} exist")) -def journal_should_not_exist(config_data, should_or_should_not): - scoped_config = scope_config(config_data, "default") - expected_path = scoped_config["journal"] - - contains_files = does_directory_contain_files(expected_path, ".") - - if should_or_should_not == "should": - assert contains_files - elif should_or_should_not == "should not": - assert not contains_files - else: - raise Exception( - "should_or_should_not valid values are 'should' or 'should not'" - ) - - -@then(parse('the content of file "{file_path}" in the cache should be\n{file_content}')) -def content_of_file_should_be(file_path, file_content, cache_dir): - assert cache_dir["exists"] - expected_content = file_content.strip().splitlines() - - with open(os.path.join(cache_dir["path"], file_path), "r") as f: - actual_content = f.read().strip().splitlines() - - for actual_line, expected_line in zip(actual_content, expected_content): - if actual_line.startswith("tags: ") and expected_line.startswith("tags: "): - assert_equal_tags_ignoring_order( - actual_line, expected_line, actual_content, expected_content - ) - else: - assert actual_line.strip() == expected_line.strip(), [ - [actual_line.strip(), expected_line.strip()], - [actual_content, expected_content], - ] - - -@then(parse("the cache should contain the files\n{file_list}")) -def cache_dir_contains_files(file_list, cache_dir): - assert cache_dir["exists"] - - actual_files = os.listdir(cache_dir["path"]) - expected_files = file_list.split("\n") - - # sort to deal with inconsistent default file ordering on different OS's - actual_files.sort() - expected_files.sort() - - assert actual_files == expected_files, [actual_files, expected_files] - - -@then(parse("the output should be valid {language_name}")) -def assert_output_is_valid_language(cli_run, language_name): - language_name = language_name.upper() - if language_name == "XML": - xml_tree = ElementTree.fromstring(cli_run["stdout"]) - assert xml_tree, "Invalid XML" - elif language_name == "JSON": - assert json.loads(cli_run["stdout"]), "Invalid JSON" - else: - assert False, f"Language name {language_name} not recognized" - - -@then(parse('"{node_name}" in the parsed output should have {number:d} elements')) -def assert_parsed_output_item_count(node_name, number, parsed_output): - lang = parsed_output["lang"] - obj = parsed_output["obj"] - - if lang == "XML": - xml_node_names = (node.tag for node in obj) - assert node_name in xml_node_names, str(list(xml_node_names)) - - actual_entry_count = len(obj.find(node_name)) - assert actual_entry_count == number, actual_entry_count - - elif lang == "JSON": - my_obj = obj - - for node in node_name.split("."): - try: - my_obj = my_obj[int(node)] - except ValueError: - assert node in my_obj - my_obj = my_obj[node] - - assert len(my_obj) == number, len(my_obj) - - else: - assert False, f"Language name {lang} not recognized" - - -@then(parse('"{field_name}" in the parsed output should {comparison}\n{expected_keys}')) -def assert_output_field_content(field_name, comparison, expected_keys, parsed_output): - lang = parsed_output["lang"] - obj = parsed_output["obj"] - expected_keys = expected_keys.split("\n") - if len(expected_keys) == 1: - expected_keys = expected_keys[0] - - if lang == "XML": - xml_node_names = (node.tag for node in obj) - assert field_name in xml_node_names, str(list(xml_node_names)) - - if field_name == "tags": - actual_tags = set(t.attrib["name"] for t in obj.find("tags")) - assert set(actual_tags) == set(expected_keys), [ - actual_tags, - set(expected_keys), - ] - else: - assert False, "This test only works for tags in XML" - - elif lang == "JSON": - my_obj = obj - - for node in field_name.split("."): - try: - my_obj = my_obj[int(node)] - except ValueError: - assert node in my_obj, [my_obj.keys(), node] - my_obj = my_obj[node] - - if comparison == "be": - if type(my_obj) is str: - assert expected_keys == my_obj, [my_obj, expected_keys] - else: - assert set(expected_keys) == set(my_obj), [ - set(my_obj), - set(expected_keys), - ] - elif comparison == "contain": - if type(my_obj) is str: - assert expected_keys in my_obj, [my_obj, expected_keys] - else: - assert all(elem in my_obj for elem in expected_keys), [ - my_obj, - expected_keys, - ] - else: - assert False, f"Language name {lang} not recognized" - - -@then(parse('there should be {number:d} "{item}" elements')) -def count_elements(number, item, cli_run): - actual_output = cli_run["stdout"] - xml_tree = ElementTree.fromstring(actual_output) - assert len(xml_tree.findall(".//" + item)) == number - - -@then(parse("the editor should have been called")) -@then(parse("the editor should have been called with {num_args} arguments")) -def count_editor_args(num_args, cli_run, editor_state): - assert cli_run["mocks"]["editor"].called - - if isinstance(num_args, int): - assert len(editor_state["command"]) == int(num_args) - - -@then(parse('the editor filename should end with "{suffix}"')) -def editor_filename_suffix(suffix, editor_state): - editor_filename = editor_state["tmpfile"]["name"] - - assert editor_state["tmpfile"]["name"].endswith(suffix), (editor_filename, suffix) - - -@then(parse('the editor file content should {comparison} "{str_value}"')) -@then(parse("the editor file content should {comparison} empty")) -@then(parse("the editor file content should {comparison}\n{str_value}")) -def contains_editor_file(comparison, str_value, editor_state): - content = editor_state["tmpfile"]["content"] - # content = f'\n"""\n{content}\n"""\n' - if comparison == "be": - assert content == str_value - elif comparison == "contain": - assert str_value in content - else: - assert False, f"Comparison '{comparison}' not supported" diff --git a/tests/step_defs/when_steps.py b/tests/step_defs/when_steps.py deleted file mode 100644 index 2e72173b..00000000 --- a/tests/step_defs/when_steps.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -from contextlib import ExitStack -import os -from unittest.mock import patch - -from pytest_bdd import parsers -from pytest_bdd import when -from pytest_bdd.parsers import parse - -from jrnl.cli import cli -from jrnl.os_compat import split_args - - -@when(parse('we change directory to "{directory_name}"')) -def when_we_change_directory(directory_name): - if not os.path.isdir(directory_name): - os.mkdir(directory_name) - - os.chdir(directory_name) - - -@when(parse('we run "jrnl {command}" and {input_method}\n{user_input}')) -@when( - parsers.re( - 'we run "jrnl (?P[^"]+)" and (?Penter|pipe) "(?P[^"]+)"' - ) -) -@when(parse('we run "jrnl" and {input_method} "{user_input}"')) -@when(parse('we run "jrnl {command}"')) -@when('we run "jrnl "') -@when('we run "jrnl"') -def we_run( - command, - config_path, - user_input, - cli_run, - capsys, - password, - cache_dir, - editor, - keyring, - input_method, - mocks, -): - assert input_method in ["", "enter", "pipe"] - is_tty = input_method != "pipe" - - if cache_dir["exists"]: - command = command.format(cache_dir=cache_dir["path"]) - - args = split_args(command) - status = 0 - - if user_input: - user_input = user_input.splitlines() if is_tty else [user_input] - - if password: - password = password.splitlines() - - if not password and user_input: - password = user_input - - with ExitStack() as stack: - - stack.enter_context(patch("sys.argv", ["jrnl"] + args)) - - mock_stdin = stack.enter_context( - patch("sys.stdin.read", side_effect=user_input) - ) - stack.enter_context(patch("sys.stdin.isatty", return_value=is_tty)) - mock_input = stack.enter_context( - patch("builtins.input", side_effect=user_input) - ) - mock_getpass = stack.enter_context( - patch("getpass.getpass", side_effect=password) - ) - - if "datetime" in mocks: - stack.enter_context(mocks["datetime"]) - stack.enter_context(mocks["calendar_parse"]) - - # stack.enter_context(patch("datetime.datetime", new=mocks["datetime"])) - # stack.enter_context(patch("jrnl.time.__get_pdt_calendar", return_value=mocks["calendar_parse"])) - - stack.enter_context( - patch("jrnl.install.get_config_path", return_value=config_path) - ) - stack.enter_context( - patch("jrnl.config.get_config_path", return_value=config_path) - ) - mock_editor = stack.enter_context(patch("subprocess.call", side_effect=editor)) - - try: - cli(args) - except StopIteration: - # This happens when input is expected, but don't have any input left - pass - except SystemExit as e: - status = e.code - - captured = capsys.readouterr() - - cli_run["status"] = status - cli_run["stdout"] = captured.out - cli_run["stderr"] = captured.err - cli_run["mocks"] = { - "stdin": mock_stdin, - "input": mock_input, - "getpass": mock_getpass, - "editor": mock_editor, - }