Skip to content

Commit

Permalink
squashed: switch to pytest for quickstarted projects
Browse files Browse the repository at this point in the history
  • Loading branch information
CastixGitHub committed Dec 18, 2020
1 parent c93d006 commit d8c9f69
Show file tree
Hide file tree
Showing 20 changed files with 501 additions and 668 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ TGTest-*
devtools/tests/data/
dist/
build/
\#*\#
.\#*
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ python:
- "3.6"
- "3.7"
- "3.8"
- "3.9-dev"

install:
- "pip install --upgrade setuptools"
Expand Down
11 changes: 11 additions & 0 deletions devtools/gearbox/quickstart/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,14 @@ def overwrite_templates(template_type):
# remove existing migrations directory
package_migrations_dir = os.path.abspath('migration')
shutil.rmtree(package_migrations_dir, ignore_errors=True)

tests_dir = os.path.abspath(os.path.join(opts.package, 'tests'))
if not opts.database:
print('database support disabled, stripping away model tests')
os.remove(os.path.abspath(tests_dir + '/_conftest/models.py'))
shutil.rmtree(os.path.abspath(tests_dir + '/models'))
if not opts.auth:
print('auth disabled, removing relative tests')
os.remove(os.path.abspath(tests_dir + '/functional/test_authentication.py'))
if opts.database:
os.remove(os.path.abspath(tests_dir + '/models/test_auth.py'))
19 changes: 19 additions & 0 deletions devtools/gearbox/quickstart/template/+dot+coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# refer to https://coverage.readthedocs.io/en/latest/config.html
[run]
source = {{package}}

[report]
show_missing = True

# if you don't omit tests directory you have more chances of seeing two tests with same name
omit =
setup.py
migration/*
# tests/*

# fail test suite if coverage drops below 100% (if you uncomment it)
# this does not work for nosetests, set it in setup.cfg (min-cover-percentage)
# fail_under = 100

# Don’t include files in the report that are 100% covered files
skip_covered = True
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ from tg import FullStackApplicationConfigurator
import {{package}}
from {{package}} import model, lib

{{if auth}}
from tg.exceptions import HTTPFound
try:
from urllib.parse import parse_qs, urlencode
except ImportError: # pragma: no cover # py2.7 compatibility
from urlparse import parse_qs
from urllib import urlencode
{{endif}}


base_config = FullStackApplicationConfigurator()

# General configuration
Expand Down Expand Up @@ -115,13 +125,6 @@ class ApplicationAuthMetadata(TGAuthMetadata):
login = None

if login is None:
try:
from urllib.parse import parse_qs, urlencode
except ImportError:
from urlparse import parse_qs
from urllib import urlencode
from tg.exceptions import HTTPFound

params = parse_qs(environ['QUERY_STRING'])
params.pop('password', None) # Remove password in case it was there
if user is None:
Expand Down Expand Up @@ -162,13 +165,6 @@ class ApplicationAuthMetadata(TGAuthMetadata):
login = None

if login is None:
try:
from urllib.parse import parse_qs, urlencode
except ImportError:
from urlparse import parse_qs
from urllib import urlencode
from tg.exceptions import HTTPFound

params = parse_qs(environ['QUERY_STRING'])
params.pop('password', None) # Remove password in case it was there
if user is None:
Expand Down Expand Up @@ -235,7 +231,7 @@ try:
# Enable DebugBar if available, install tgext.debugbar to turn it on
from tgext.debugbar import enable_debugbar
enable_debugbar(base_config)
except ImportError:
except ImportError: # pragma: no cover
pass
{{endif}}

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,4 @@ def icon(icon_name):
# Import commonly used helpers from WebHelpers2 and TG
from tg.util.html import script_json_encode

try:
from webhelpers2 import date, html, number, misc, text
except SyntaxError:
log.error("WebHelpers2 helpers not available with this Python Version")
from webhelpers2 import date, html, number, misc, text
16 changes: 12 additions & 4 deletions devtools/gearbox/quickstart/template/+package+/model/auth.py_tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class Group(DeclarativeBase):
def __repr__(self):
return '<Group: name=%s>' % repr(self.group_name)

def __unicode__(self):
def __str__(self):
return self.group_name


Expand Down Expand Up @@ -102,15 +102,15 @@ class User(DeclarativeBase):
repr(self.display_name)
)

def __unicode__(self):
def __str__(self):
return self.display_name or self.user_name

@property
def permissions(self):
"""Return a set with all permissions granted to the user."""
perms = set()
for g in self.groups:
perms = perms | set(g.permissions)
perms.update(g.permissions)
return perms

@classmethod
Expand Down Expand Up @@ -192,7 +192,7 @@ class Permission(DeclarativeBase):
def __repr__(self):
return '<Permission: name=%s>' % repr(self.permission_name)

def __unicode__(self):
def __str__(self):
return self.permission_name

{{elif auth == 'ming'}}
Expand Down Expand Up @@ -292,6 +292,11 @@ class User(MappedClass):
def permissions(self):
return Permission.query.find(dict(_groups={'$in':self._groups})).all()

@classmethod
def by_user_name(cls, user_name):
"""Return the user object whose user name is ``user_name``."""
return cls.query.get(user_name=user_name)

@classmethod
def by_email_address(cls, email):
"""Return the user object whose email address is ``email``."""
Expand All @@ -313,4 +318,7 @@ class User(MappedClass):
hash.update((password + self.password[:64]).encode('utf-8'))
return self.password[64:] == hash.hexdigest()

def __eq__(self, other):
return self._id == other._id

{{endif}}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import pytest
from webtest import TestApp as WebTestApp # rename due to pytest warning
from paste.deploy import loadapp, appconfig
from tg import config
from {{package}} import websetup
{{if database}}from {{package}} import model{{endif}}
from os import getcwd
{{if sqlalchemy}}import transaction{{endif}}


{{if database}}
def teardown_db():
{{if sqlalchemy}}
model.DBSession.remove()
engine = config['tg.app_globals'].sa_engine
model.metadata.drop_all(engine)
transaction.abort()
{{elif ming}}
datastore = config['tg.app_globals'].ming_datastore
model.DBSession.clear() # before dropping flush is performed
try:
# On MIM drop all data
datastore.conn.drop_all()
except TypeError: # pragma: no cover
# On MongoDB drop database
datastore.conn.drop_database(datastore.db)
{{endif}}
{{endif}}


@pytest.fixture(scope='function')
def _app():
"""This fixture allows you to reconfigure the application configuration.
Also, you can omit setup_app command"""
def __app(name='main_without_authn', reconfig=None, setup_app=True):
paste_config = 'config:test.ini#%s' % name
app = WebTestApp(loadapp(
paste_config,
relative_to=getcwd(),
global_conf=reconfig or {},
))
if setup_app:
_config = appconfig(paste_config, relative_to=getcwd(), global_conf=reconfig or {})
websetup.setup_app(None, _config, {})
return app
yield __app
{{if database}}teardown_db(){{endif}}


@pytest.fixture(scope='function')
def app(_app):
"""This fixture is the default application"""
return _app()


{{if auth}}
@pytest.fixture()
def env():
"""this is just a shorthand intended to be passed to extra_environ in webtest calls,
remote_user got as parameter will go into REMOTE_USER key,
other kwarguments are included in the returned dictionary"""
def _environ(remote_user, **kwargs):
r = {'REMOTE_USER': remote_user} if remote_user else {}
r.update(kwargs)
return r
return _environ
{{endif}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pytest
from {{package}}.model import DBSession
from {{package}}.tests._conftest.app import teardown_db


@pytest.fixture()
def obj():
def _obj(klass, attrs):
new_attrs = {}
new_attrs.update(attrs)
created = klass(**new_attrs)
{{if sqlalchemy}}
DBSession.add(created)
DBSession.flush()
{{elif ming}}
created.__mongometa__.session.flush()
created.__mongometa__.session.clear()
{{endif}}
return created
yield _obj
teardown_db()
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{if database}}from {{package}}.tests._conftest.models import obj{{endif}}
from {{package}}.tests._conftest.app import app, _app{{if auth}}, env{{endif}}

# Fixtures defined in _conftest came from turbogears2, change them if you wish

# Place here your own fixtures.

This file was deleted.

Loading

0 comments on commit d8c9f69

Please sign in to comment.