From 7849d844409cebd5fd1897282050e356f4bf853c Mon Sep 17 00:00:00 2001 From: Subhash Bhushan Date: Thu, 2 Jul 2020 08:17:50 -0700 Subject: [PATCH] Simplify Project Structure with bare minimum requirements Links to Protean 0.5.0 --- LICENSE | 4 +- README.rst | 29 +---- cookiecutter.json | 25 ++--- {{cookiecutter.repo_name}}/.cookiecutterrc | 4 +- {{cookiecutter.repo_name}}/README.rst | 2 +- {{cookiecutter.repo_name}}/protean.ini | 1 - {{cookiecutter.repo_name}}/requirements.txt | 1 - .../requirements/dev.txt | 4 - .../requirements/prod.txt | 1 - .../requirements/test.txt | 6 - {{cookiecutter.repo_name}}/setup.cfg | 3 +- {{cookiecutter.repo_name}}/setup.py | 103 +++++++++--------- .../{{cookiecutter.package_name}}/__main__.py | 14 --- .../src/{{cookiecutter.package_name}}/cli.py | 36 ------ .../{{cookiecutter.package_name}}/config.py | 77 +++++++++++++ .../{{cookiecutter.package_name}}/domain.py | 21 ++++ {{cookiecutter.repo_name}}/tests/__init__.py | 0 {{cookiecutter.repo_name}}/tests/config.py | 77 +++++++++++++ {{cookiecutter.repo_name}}/tests/conftest.py | 61 +++++++---- .../tests/support/config.py | 0 20 files changed, 282 insertions(+), 187 deletions(-) delete mode 100644 {{cookiecutter.repo_name}}/protean.ini delete mode 100644 {{cookiecutter.repo_name}}/requirements.txt delete mode 100644 {{cookiecutter.repo_name}}/requirements/dev.txt delete mode 100644 {{cookiecutter.repo_name}}/requirements/prod.txt delete mode 100644 {{cookiecutter.repo_name}}/requirements/test.txt delete mode 100644 {{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/__main__.py delete mode 100644 {{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/cli.py create mode 100644 {{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/config.py create mode 100644 {{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/domain.py delete mode 100644 {{cookiecutter.repo_name}}/tests/__init__.py create mode 100644 {{cookiecutter.repo_name}}/tests/config.py delete mode 100644 {{cookiecutter.repo_name}}/tests/support/config.py diff --git a/LICENSE b/LICENSE index ba4b310..ce51337 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2019, Subhash Bhushan C +Copyright (c) 2018-20, Subhash Bhushan C All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following @@ -20,4 +20,4 @@ SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, I CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +POSSIBILITY OF SUCH DAMAGE. diff --git a/README.rst b/README.rst index ebb4e15..d58bca6 100644 --- a/README.rst +++ b/README.rst @@ -11,13 +11,13 @@ Notes: This template chooses some project implementations to be available default: -* Pytest_ for testing the business logic +* Pytest_ as the Test Framework * bumpversion_ for maintaining a semantic version Requirements ------------ -Projects using this template have these minimal dependencies: +Projects using this template have these dependencies: * Cookiecutter_ - just for creating the project * Setuptools_ - for building the package, wheels etc. Setuptools is now packaged by default with most Python Virtual environment managers. @@ -112,30 +112,13 @@ You will be asked for these fields: "0.1.0" - Release version (see ``.bumpversion.cfg``). - * - ``command_line_interface`` - - .. code:: python - - "plain" - - Option to enable a CLI (a bin/executable file). Available options: - - * ``plain`` - a very simple command. - * ``argparse`` - a command implemented with ``argparse``. - * ``click`` - a command implemented with `click `_ - which you can use to build more complex commands. - * ``no`` - no CLI at all. - - * - ``command_line_interface_bin_name`` - - .. code:: python - - "domain" - - Name of the CLI bin/executable file (set the console script name in ``setup.py``). - After this you can create the initial repository (make sure you `create `_ an *empty* Github project):: git init . git add . - git commit -m "Initial skel." - git remote add origin git@github.com:subhashb/python-domain.git + git commit -m "Initial commit" + git remote add origin git@github.com:/.git git push -u origin master Developing the project @@ -145,10 +128,6 @@ To run all the tests, just run:: pytest -Releasing the project -````````````````````` -Before releasing your package on PyPI you should have all the tox environments passing. - Version management '''''''''''''''''' diff --git a/cookiecutter.json b/cookiecutter.json index df6ed0c..410e865 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -1,19 +1,12 @@ { - "full_name": "Subhash Bhushan C", - "email": "subhash.bhushan@gmail.com", - "website": "https://proteanhq.com", - "github_username": "subhashb", - "project_name": "Domain", - "repo_name": "protean-{{ cookiecutter.project_name|lower|replace(' ','-') }}", + "full_name": "John Doe", + "email": "john.doe.12345@gmail.com", + "website": "https://johndoe12345.com", + "github_username": "johndoe", + "project_name": "New Project", + "repo_name": "{{ cookiecutter.project_name|lower|replace(' ','-') }}", "package_name": "{{ cookiecutter.project_name|lower|replace(' ','_')|replace('-','_') }}", "distribution_name": "{{ cookiecutter.package_name|replace('_','-') }}", - "project_short_description": "A basic Protean Application package. Generated with cookiecutter-protean.", - "version": "0.0.1", - "command_line_interface": [ - "plain", - "argparse", - "click", - "no" - ], - "command_line_interface_bin_name": "{{ cookiecutter.distribution_name }}" - } \ No newline at end of file + "project_short_description": "{{ cookiecutter.project_name }} - A basic Protean Application, generated with cookiecutter-protean.", + "version": "0.0.1" +} diff --git a/{{cookiecutter.repo_name}}/.cookiecutterrc b/{{cookiecutter.repo_name}}/.cookiecutterrc index 89c4b10..e75b1d6 100644 --- a/{{cookiecutter.repo_name}}/.cookiecutterrc +++ b/{{cookiecutter.repo_name}}/.cookiecutterrc @@ -1,3 +1,5 @@ +# cSpell: disable + # This file exists so you can easily regenerate your project. # # `cookiepatcher` is a convenient shim around `cookiecutter` @@ -17,4 +19,4 @@ default_context: {% for key, value in cookiecutter.items()|sort %} {{ "{0:26}".format(key + ":") }} {{ "{0!r}".format(value).strip("u") }} -{%- endfor %} \ No newline at end of file +{%- endfor %} diff --git a/{{cookiecutter.repo_name}}/README.rst b/{{cookiecutter.repo_name}}/README.rst index bfb5004..1f2fbc0 100644 --- a/{{cookiecutter.repo_name}}/README.rst +++ b/{{cookiecutter.repo_name}}/README.rst @@ -2,7 +2,7 @@ Overview ======== -{{ cookiecutter.project_name }} - {{ cookiecutter.version }} +##{{ cookiecutter.project_name }} - {{ cookiecutter.version }} {{ cookiecutter.project_short_description|wordwrap(119) }} diff --git a/{{cookiecutter.repo_name}}/protean.ini b/{{cookiecutter.repo_name}}/protean.ini deleted file mode 100644 index eea2c18..0000000 --- a/{{cookiecutter.repo_name}}/protean.ini +++ /dev/null @@ -1 +0,0 @@ -[pytest] diff --git a/{{cookiecutter.repo_name}}/requirements.txt b/{{cookiecutter.repo_name}}/requirements.txt deleted file mode 100644 index 3e2d68e..0000000 --- a/{{cookiecutter.repo_name}}/requirements.txt +++ /dev/null @@ -1 +0,0 @@ --r requirements/prod.txt \ No newline at end of file diff --git a/{{cookiecutter.repo_name}}/requirements/dev.txt b/{{cookiecutter.repo_name}}/requirements/dev.txt deleted file mode 100644 index a67d57f..0000000 --- a/{{cookiecutter.repo_name}}/requirements/dev.txt +++ /dev/null @@ -1,4 +0,0 @@ --r prod.txt - -flake8==3.5.0 -bumpversion==0.5.3 \ No newline at end of file diff --git a/{{cookiecutter.repo_name}}/requirements/prod.txt b/{{cookiecutter.repo_name}}/requirements/prod.txt deleted file mode 100644 index 4f3a162..0000000 --- a/{{cookiecutter.repo_name}}/requirements/prod.txt +++ /dev/null @@ -1 +0,0 @@ -protean==0.0.10 \ No newline at end of file diff --git a/{{cookiecutter.repo_name}}/requirements/test.txt b/{{cookiecutter.repo_name}}/requirements/test.txt deleted file mode 100644 index e61ca8e..0000000 --- a/{{cookiecutter.repo_name}}/requirements/test.txt +++ /dev/null @@ -1,6 +0,0 @@ --r dev.txt - -mock==2.0.0 -pluggy==0.9.0 -pytest==4.4.1 -pytest-flake8==1.0.4 diff --git a/{{cookiecutter.repo_name}}/setup.cfg b/{{cookiecutter.repo_name}}/setup.cfg index 7f0cff2..791f075 100644 --- a/{{cookiecutter.repo_name}}/setup.cfg +++ b/{{cookiecutter.repo_name}}/setup.cfg @@ -1,3 +1,2 @@ [flake8] -max-line-length = 199 -exclude = tests/*.py +max-line-length = 119 diff --git a/{{cookiecutter.repo_name}}/setup.py b/{{cookiecutter.repo_name}}/setup.py index 24f03cc..b9401f2 100644 --- a/{{cookiecutter.repo_name}}/setup.py +++ b/{{cookiecutter.repo_name}}/setup.py @@ -1,81 +1,78 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -from __future__ import absolute_import -from __future__ import print_function -import io -import re +from __future__ import absolute_import, print_function + +import io, re from glob import glob -from os.path import basename -from os.path import dirname -from os.path import join -from os.path import splitext +from os.path import basename, dirname, join, splitext -from setuptools import find_packages -from setuptools import setup +# ThirdParty Library Imports +from setuptools import find_packages, setup def read(*names, **kwargs): with io.open( - join(dirname(__file__), *names), - encoding=kwargs.get('encoding', 'utf8') + join(dirname(__file__), *names), encoding=kwargs.get("encoding", "utf8") ) as fh: return fh.read() +testing_requires = [ + "flake8-commas==2.0.0", + "future==0.18.2", + "mock==4.0.2", + "pytest-bdd==3.2.1", + "pytest-cov==2.8.1", + "pytest-flake8==1.0.4", + "pytest-flask==0.15.1", + "pytest-freezegun==0.4.1", + "pytest-mock==2.0.0", + "pytest==5.2.1", +] + +dev_requires = testing_requires + [ + "bump2version==1.0.0", +] + setup( - name='{{ cookiecutter.distribution_name }}', - version='{{ cookiecutter.version }}', - description={{ '{0!r}'.format(cookiecutter.project_short_description).lstrip('ub') }}, - long_description='%s\n%s' % ( - re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub('', read('README.rst')), - re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst')) + name="{{ cookiecutter.distribution_name }}", + version="{{ cookiecutter.version }}", + description={{"{0!r}".format(cookiecutter.project_short_description).lstrip("ub")}}, + long_description="%s\n%s" + % ( + re.compile("^.. start-badges.*^.. end-badges", re.M | re.S).sub( + "", read("README.rst") + ), + re.sub(":[a-z]+:`~?(.*?)`", r"``\1``", read("CHANGELOG.rst")), ), - author={{ '{0!r}'.format(cookiecutter.full_name).lstrip('ub') }}, - author_email={{ '{0!r}'.format(cookiecutter.email).lstrip('ub') }}, - url='https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.repo_name }}', - packages=find_packages('src'), - package_dir={'': 'src'}, - py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')], + author={{"{0!r}".format(cookiecutter.full_name).lstrip("ub")}}, + author_email={{"{0!r}".format(cookiecutter.email).lstrip("ub")}}, + url="https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.repo_name }}", + packages=find_packages("src"), + package_dir={"": "src"}, + py_modules=[splitext(basename(path))[0] for path in glob("src/*.py")], include_package_data=True, zip_safe=False, classifiers=[ - # complete classifier list: http://pypi.python.org/pypi?%3Aaction=list_classifiers - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'Operating System :: Unix', - 'Operating System :: POSIX', - 'Operating System :: Microsoft :: Windows', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3 :: Only', - 'Topic :: Utilities', + "Programming Language :: Python", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3 :: Only", ], - project_urls={ - 'Issue Tracker': 'https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.repo_name }}/issues', - }, keywords=[ # eg: 'keyword1', 'keyword2', 'keyword3', ], - python_requires='>=3.6', + python_requires=">=3.7", install_requires=[ - 'protean==0.0.10', -{%- if cookiecutter.command_line_interface == 'click' %} - 'click', -{%- endif %} + "protean==0.5.0", # eg: 'aspectlib==1.1.1', 'six>=1.7', ], extras_require={ - 'dev': ['check-manifest'], - 'test': ['coverage'], - }, -{%- if cookiecutter.command_line_interface != 'no' %} - entry_points={ - 'console_scripts': [ - '{{ cookiecutter.command_line_interface_bin_name }} = {{ cookiecutter.package_name }}.cli:main', - ] + "test": testing_requires, + "tests": testing_requires, + "testing": testing_requires, + "dev": dev_requires, + "all": dev_requires, }, -{%- endif %} ) diff --git a/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/__main__.py b/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/__main__.py deleted file mode 100644 index 37702a7..0000000 --- a/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/__main__.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -Entrypoint module, in case you use `python -mprotean`. - - -Why does this file exist, and why __main__? For more info, read: - -- https://www.python.org/dev/peps/pep-0338/ -- https://docs.python.org/2/using/cmdline.html#cmdoption-m -- https://docs.python.org/3/using/cmdline.html#cmdoption-m -""" -from {{ cookiecutter.package_name }}.cli import main - -if __name__ == "__main__": - main() diff --git a/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/cli.py b/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/cli.py deleted file mode 100644 index 6b5591d..0000000 --- a/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/cli.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -Module that contains the command line app. - -Why does this file exist, and why not put this in __main__? - - You might be tempted to import things from __main__ later, but that will cause - problems: the code will get executed twice: - - - When you run `python -mprotean` python will execute - ``__main__.py`` as a script. That means there won't be any - ``protean.__main__`` in ``sys.modules``. - - When you import __main__ it will get executed again (as a module) because - there's no ``protean.__main__`` in ``sys.modules``. - - Also see (1) from http://click.pocoo.org/5/setuptools/#setuptools-integration -""" -import click - - -@click.group(invoke_without_command=True) -@click.version_option() -@click.pass_context -def main(ctx): - """CLI utilities for the {{ cookiecutter.project_name }}""" - if ctx.invoked_subcommand is None: - click.echo(ctx.get_help()) - - -@main.command() -def test(): - import pytest - import sys - - errno = pytest.main(['-v', '--flake8']) - - sys.exit(errno) diff --git a/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/config.py b/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/config.py new file mode 100644 index 0000000..98e1f01 --- /dev/null +++ b/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/config.py @@ -0,0 +1,77 @@ +# cSpell: disable + +import datetime +import os + +from protean.utils import Database, IdentityStrategy + + +DEBUG = True + +# Parse domain directory and autoload domain modules +AUTOLOAD_DOMAIN = True + +# A secret key for this particular Protean installation. Used in secret-key +# hashing algorithms. +SECRET_KEY = "1$jp0neQpaU8issDzX4uQ*eEfDEh$TOOKd$fFJBRyDQNvUl25y" + +# Flag indicates that we are testing +TESTING = True + +# Database Configuration +DATABASES = { + "default": {"PROVIDER": "protean.impl.repository.dict_repo.DictProvider"}, + "sqlite": { + "PROVIDER": "protean.impl.repository.sqlalchemy_repo.SAProvider", + "DATABASE": Database.SQLITE.value, + "DATABASE_URI": "sqlite:///test.db", + }, + "postgres": { + "PROVIDER": "protean.impl.repository.sqlalchemy_repo.SAProvider", + "DATABASE": Database.POSTGRESQL.value, + "DATABASE_URI": os.getenv( + "POSTGRESQL_DATABASE_URI", + "postgresql://{{ cookiecutter.package_name }}:pwd@localhost:5432/{{ cookiecutter.package_name }}_dev", + ), + }, +} + +# Identity strategy to use when persisting Entities/Aggregates. +# +# Options: +# +# * IdentityStrategy.UUID: Default option, and preferred. Identity is a UUID and generated during `build` time. +# Persisted along with other details into the data store. +# * IdentityStrategy.DATABASE: Let the database generate unique identity during persistence +# * IdentityStrategy.FUNCTION: Special function that returns a unique identifier +IDENTITY_STRATEGY = IdentityStrategy.UUID + +# Messaging Mediums +BROKERS = { + "default": {"PROVIDER": "protean.impl.broker.memory_broker.MemoryBroker",}, + "celery": { + "PROVIDER": "protean.impl.broker.celery_broker.CeleryBroker", + "URI": os.environ.get("BROKER_URI") or "redis://127.0.0.1:6379/2", + "IS_ASYNC": True, + }, +} + +LOGGING_CONFIG = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "console": {"format": "%(asctime)s %(name)-12s %(levelname)-8s %(message)s",}, + }, + "handlers": { + "console": { + "level": "INFO", + "class": "logging.StreamHandler", + "formatter": "console", + }, + }, + "loggers": { + "protean": {"handlers": ["console"], "level": "INFO",}, + "protean.impl.broker.celery": {"handlers": ["console"], "level": "INFO",}, + "{{ cookiecutter.package_name }}": {"handlers": ["console"], "level": "INFO",}, + }, +} diff --git a/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/domain.py b/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/domain.py new file mode 100644 index 0000000..90b7156 --- /dev/null +++ b/{{cookiecutter.repo_name}}/src/{{cookiecutter.package_name}}/domain.py @@ -0,0 +1,21 @@ +import logging +import logging.config +import os + +from protean.domain import Domain + +domain = Domain("{{ cookiecutter.project_name }}") + +current_path = os.path.abspath(os.path.dirname(__file__)) +config_path = os.path.join(current_path, "./config.py") +domain.config.from_pyfile(config_path) + +logging.config.dictConfig(domain.config["LOGGING_CONFIG"]) + +domain.init() + +# Enable Event Logging +# +# from protean.infra.event_log import EventLog, EventLogRepository +# domain.register(EventLog) +# domain.register(EventLogRepository) diff --git a/{{cookiecutter.repo_name}}/tests/__init__.py b/{{cookiecutter.repo_name}}/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/{{cookiecutter.repo_name}}/tests/config.py b/{{cookiecutter.repo_name}}/tests/config.py new file mode 100644 index 0000000..98e1f01 --- /dev/null +++ b/{{cookiecutter.repo_name}}/tests/config.py @@ -0,0 +1,77 @@ +# cSpell: disable + +import datetime +import os + +from protean.utils import Database, IdentityStrategy + + +DEBUG = True + +# Parse domain directory and autoload domain modules +AUTOLOAD_DOMAIN = True + +# A secret key for this particular Protean installation. Used in secret-key +# hashing algorithms. +SECRET_KEY = "1$jp0neQpaU8issDzX4uQ*eEfDEh$TOOKd$fFJBRyDQNvUl25y" + +# Flag indicates that we are testing +TESTING = True + +# Database Configuration +DATABASES = { + "default": {"PROVIDER": "protean.impl.repository.dict_repo.DictProvider"}, + "sqlite": { + "PROVIDER": "protean.impl.repository.sqlalchemy_repo.SAProvider", + "DATABASE": Database.SQLITE.value, + "DATABASE_URI": "sqlite:///test.db", + }, + "postgres": { + "PROVIDER": "protean.impl.repository.sqlalchemy_repo.SAProvider", + "DATABASE": Database.POSTGRESQL.value, + "DATABASE_URI": os.getenv( + "POSTGRESQL_DATABASE_URI", + "postgresql://{{ cookiecutter.package_name }}:pwd@localhost:5432/{{ cookiecutter.package_name }}_dev", + ), + }, +} + +# Identity strategy to use when persisting Entities/Aggregates. +# +# Options: +# +# * IdentityStrategy.UUID: Default option, and preferred. Identity is a UUID and generated during `build` time. +# Persisted along with other details into the data store. +# * IdentityStrategy.DATABASE: Let the database generate unique identity during persistence +# * IdentityStrategy.FUNCTION: Special function that returns a unique identifier +IDENTITY_STRATEGY = IdentityStrategy.UUID + +# Messaging Mediums +BROKERS = { + "default": {"PROVIDER": "protean.impl.broker.memory_broker.MemoryBroker",}, + "celery": { + "PROVIDER": "protean.impl.broker.celery_broker.CeleryBroker", + "URI": os.environ.get("BROKER_URI") or "redis://127.0.0.1:6379/2", + "IS_ASYNC": True, + }, +} + +LOGGING_CONFIG = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "console": {"format": "%(asctime)s %(name)-12s %(levelname)-8s %(message)s",}, + }, + "handlers": { + "console": { + "level": "INFO", + "class": "logging.StreamHandler", + "formatter": "console", + }, + }, + "loggers": { + "protean": {"handlers": ["console"], "level": "INFO",}, + "protean.impl.broker.celery": {"handlers": ["console"], "level": "INFO",}, + "{{ cookiecutter.package_name }}": {"handlers": ["console"], "level": "INFO",}, + }, +} diff --git a/{{cookiecutter.repo_name}}/tests/conftest.py b/{{cookiecutter.repo_name}}/tests/conftest.py index 6a3616c..fc0e930 100644 --- a/{{cookiecutter.repo_name}}/tests/conftest.py +++ b/{{cookiecutter.repo_name}}/tests/conftest.py @@ -1,38 +1,51 @@ -"""Module to setup Test Suite and register artifacts for tests""" - +import logging.config +import os import pytest +from protean.globals import current_domain + + +def fetch_{{ cookiecutter.package_name }}_domain(): + """Fetch the core domain for running tests + This is typically the domain to which all domain elements are registered + """ + from {{ cookiecutter.package_name }}.domain import domain + return domain + + +def configured_domain_for_session(session): + domain = fetch_{{ cookiecutter.package_name }}_domain() -def pytest_addoption(parser): - """Additional options for running tests with pytest""" - parser.addoption( - "--slow", action="store_true", default=False, help="run slow tests" - ) + # Construct relative path to config file + current_path = os.path.abspath(os.path.dirname(__file__)) + config_path = os.path.join(current_path, "./config.py") + if os.path.exists(config_path): + domain.config.from_pyfile(config_path) -def pytest_collection_modifyitems(config, items): - """Configure special markers on tests, so as to control execution""" - if config.getoption("--slow"): - # --slow given in cli: do not skip slow tests - return - skip_slow = pytest.mark.skip(reason="need --slow option to run") - for item in items: - if "slow" in item.keywords: - item.add_marker(skip_slow) + if 'LOGGING_CONFIG' in domain.config: + logging.config.dictConfig(domain.config['LOGGING_CONFIG']) + return domain -@pytest.fixture(scope="session", autouse=True) -def run_once_on_init(): - """Things to run once for the entire test suite""" - pass + +def pytest_sessionstart(session): + """Pytest hook to run before collecting tests. + + In this method, we fetch the domain and activate it, + by pushing the domain_context associated with the domain. + We can then refer to the domain everywhere else in pytest with `current_domain` + """ + domain = configured_domain_for_session(session) + domain.domain_context().push() @pytest.fixture(autouse=True) def run_around_tests(): - """Stuff to run around every test case, like Connection initialization and Data Cleanup""" - - # Do something before running each test case yield - # Do something after running each test case + from protean.globals import current_domain + + for provider in current_domain.providers_list(): + provider._data_reset() diff --git a/{{cookiecutter.repo_name}}/tests/support/config.py b/{{cookiecutter.repo_name}}/tests/support/config.py deleted file mode 100644 index e69de29..0000000