kopia lustrzana https://github.com/jedie/PyInventory
164 wiersze
5.0 KiB
Python
164 wiersze
5.0 KiB
Python
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from django.conf import settings
|
|
from django.core import checks
|
|
from django.core.cache import cache
|
|
from django.test import TestCase
|
|
from django_tools.unittest_utils.project_setup import check_editor_config
|
|
from packaging.version import Version
|
|
|
|
import inventory
|
|
|
|
|
|
PACKAGE_ROOT = Path(inventory.__file__).parent.parent.parent
|
|
|
|
|
|
def assert_file_contains_string(file_path, string):
|
|
with file_path.open('r') as f:
|
|
for line in f:
|
|
if string in line:
|
|
return
|
|
raise AssertionError(f'File {file_path} does not contain {string!r} !')
|
|
|
|
|
|
def test_version(package_root=None, version=None):
|
|
if package_root is None:
|
|
package_root = PACKAGE_ROOT
|
|
|
|
if version is None:
|
|
version = inventory.__version__
|
|
|
|
ver_obj = Version(inventory.__version__)
|
|
|
|
if not ver_obj.is_prerelease:
|
|
version_string = f'v{version}'
|
|
|
|
assert_file_contains_string(
|
|
file_path=Path(package_root, 'README.md'), string=version_string
|
|
)
|
|
|
|
assert_file_contains_string(
|
|
file_path=Path(package_root, 'pyproject.toml'),
|
|
string=f'version = "{version}"'
|
|
)
|
|
|
|
|
|
def test_poetry_check(package_root=None):
|
|
if package_root is None:
|
|
package_root = PACKAGE_ROOT
|
|
|
|
poerty_bin = shutil.which('poetry')
|
|
|
|
output = subprocess.check_output(
|
|
[poerty_bin, 'check'],
|
|
text=True,
|
|
env=os.environ,
|
|
stderr=subprocess.STDOUT,
|
|
cwd=str(package_root),
|
|
)
|
|
print(output)
|
|
assert output == 'All set!\n'
|
|
|
|
|
|
class ProjectSettingsTestCase(TestCase):
|
|
def test_project_path(self):
|
|
project_path = settings.PROJECT_PATH
|
|
assert project_path.is_dir()
|
|
assert Path(project_path, 'inventory').is_dir()
|
|
assert Path(project_path, 'inventory_project').is_dir()
|
|
|
|
def test_template_dirs(self):
|
|
assert len(settings.TEMPLATES) == 1
|
|
dirs = settings.TEMPLATES[0].get('DIRS')
|
|
assert len(dirs) == 1
|
|
template_path = Path(dirs[0]).resolve()
|
|
assert template_path.is_dir()
|
|
|
|
def test_manage_check(self):
|
|
all_issues = checks.run_checks(
|
|
app_configs=None,
|
|
tags=None,
|
|
include_deployment_checks=True,
|
|
databases=None,
|
|
)
|
|
all_issue_ids = {issue.id for issue in all_issues}
|
|
excpeted_issues = {
|
|
'security.W008', # settings.SECURE_SSL_REDIRECT=False
|
|
'async.E001', # os.environ['DJANGO_ALLOW_ASYNC_UNSAFE'] exists
|
|
}
|
|
if all_issue_ids != excpeted_issues:
|
|
print('=' * 100)
|
|
for issue in all_issues:
|
|
print(issue)
|
|
print('=' * 100)
|
|
raise AssertionError('There are check issues!')
|
|
|
|
def test_cache(self):
|
|
# django cache should work in tests, because some tests "depends" on it
|
|
cache_key = 'a-cache-key'
|
|
assert cache.get(cache_key) is None
|
|
cache.set(cache_key, 'the cache content', timeout=1)
|
|
assert cache.get(cache_key) == 'the cache content'
|
|
cache.delete(cache_key)
|
|
assert cache.get(cache_key) is None
|
|
|
|
def test_settings(self):
|
|
assert settings.SETTINGS_MODULE == 'inventory_project.settings.tests'
|
|
middlewares = [entry.rsplit('.', 1)[-1] for entry in settings.MIDDLEWARE]
|
|
assert 'AlwaysLoggedInAsSuperUserMiddleware' not in middlewares
|
|
assert 'DebugToolbarMiddleware' not in middlewares
|
|
|
|
|
|
def test_check_editor_config():
|
|
check_editor_config(package_root=PACKAGE_ROOT)
|
|
|
|
|
|
class CodeStyleTestCase(TestCase):
|
|
def call(self, prog, *args):
|
|
venv_bin_path = Path(sys.executable).parent
|
|
prog = shutil.which(prog, path=venv_bin_path)
|
|
assert prog
|
|
|
|
# Darker will call other programs like "flake8", "git"
|
|
# Use first our venv bin path:
|
|
env_path = f'{venv_bin_path}{os.pathsep}{os.environ["PATH"]}'
|
|
|
|
return subprocess.check_output(
|
|
(prog,) + args,
|
|
text=True,
|
|
env=dict(PATH=env_path),
|
|
stderr=subprocess.STDOUT,
|
|
cwd=str(PACKAGE_ROOT),
|
|
)
|
|
|
|
def check_code_style(self):
|
|
self.call('darker', '--check')
|
|
self.call('isort', '--check-only', '.')
|
|
self.call('flake8', '.')
|
|
|
|
def test_code_style(self):
|
|
# lint: ## Run code formatters and linter
|
|
# poetry run darker --check
|
|
# poetry run isort --check-only .
|
|
# poetry run flake8 .
|
|
#
|
|
# fix-code-style: ## Fix code formatting
|
|
# poetry run darker
|
|
# poetry run isort .
|
|
|
|
# First try:
|
|
try:
|
|
self.check_code_style()
|
|
except subprocess.CalledProcessError:
|
|
# Fix and test again:
|
|
try:
|
|
self.call('darker')
|
|
self.call('isort', '.')
|
|
self.check_code_style() # Check again
|
|
except subprocess.CalledProcessError as err:
|
|
raise AssertionError(f'Linting error:\n{"-"*100}\n{err.stdout}\n{"-"*100}')
|