calibre/setup/test.py
Kovid Goyal efdf661457
Remove DBUS based global menu and system tray code
This was mainly present to support GNOME and GNOME has decided to ditch
system trays and global menus. Since the python-dbus package this code
uses is not maintained, ditch it entirely.
2021-06-24 10:55:12 +05:30

208 lines
8.9 KiB
Python

#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
import os
import subprocess
import sys
import unittest
from setup import SRC, Command, islinux, ismacos, iswindows
TEST_MODULES = frozenset('srv db polish opf css docx cfi matcher icu smartypants build misc dbcli ebooks'.split())
class TestImports(unittest.TestCase):
def base_check(self, base, exclude_packages, exclude_modules):
import importlib
import_base = os.path.dirname(base)
count = 0
for root, dirs, files in os.walk(base):
for d in tuple(dirs):
if not os.path.isfile(os.path.join(root, d, '__init__.py')):
dirs.remove(d)
for fname in files:
module_name, ext = os.path.splitext(fname)
if ext != '.py':
continue
path = os.path.join(root, module_name)
relpath = os.path.relpath(path, import_base).replace(os.sep, '/')
full_module_name = '.'.join(relpath.split('/'))
if full_module_name.endswith('.__init__'):
full_module_name = full_module_name.rpartition('.')[0]
if full_module_name in exclude_modules or ('.' in full_module_name and full_module_name.rpartition('.')[0] in exclude_packages):
continue
importlib.import_module(full_module_name)
count += 1
return count
def test_import_of_all_python_modules(self):
exclude_packages = {'calibre.devices.mtp.unix.upstream'}
exclude_modules = set()
if not iswindows:
exclude_modules |= {'calibre.utils.iphlpapi', 'calibre.utils.open_with.windows', 'calibre.devices.winusb'}
exclude_packages |= {'calibre.utils.winreg', 'calibre.utils.windows'}
if not ismacos:
exclude_modules.add('calibre.utils.open_with.osx')
if not islinux:
exclude_modules |= {
'calibre.linux',
'calibre.utils.linux_trash', 'calibre.utils.open_with.linux',
'calibre.gui2.linux_file_dialogs'
}
self.assertGreater(self.base_check(os.path.join(SRC, 'odf'), exclude_packages, exclude_modules), 10)
base = os.path.join(SRC, 'calibre')
self.assertGreater(self.base_check(base, exclude_packages, exclude_modules), 1000)
import calibre.web.feeds.feedparser as f
del f
from calibre.ebooks.markdown import Markdown
del Markdown
def find_tests(which_tests=None, exclude_tests=None):
ans = []
a = ans.append
def ok(x):
return (not which_tests or x in which_tests) and (not exclude_tests or x not in exclude_tests)
if ok('build'):
from calibre.test_build import find_tests
a(find_tests())
if ok('srv'):
from calibre.srv.tests.main import find_tests
a(find_tests())
if ok('db'):
from calibre.db.tests.main import find_tests
a(find_tests())
if ok('polish'):
from calibre.ebooks.oeb.polish.tests.main import find_tests
a(find_tests())
if ok('opf'):
from calibre.ebooks.metadata.opf2 import suite
a(suite())
from calibre.ebooks.metadata.opf3_test import suite
a(suite())
if ok('css'):
from tinycss.tests.main import find_tests
a(find_tests())
from calibre.ebooks.oeb.normalize_css import test_normalization
a(test_normalization(return_tests=True))
from calibre.ebooks.css_transform_rules import test
a(test(return_tests=True))
from css_selectors.tests import find_tests
a(find_tests())
if ok('docx'):
from calibre.ebooks.docx.fields import test_parse_fields
a(test_parse_fields(return_tests=True))
from calibre.ebooks.docx.writer.utils import test_convert_color
a(test_convert_color(return_tests=True))
if ok('cfi'):
from calibre.ebooks.epub.cfi.tests import find_tests
a(find_tests())
if ok('matcher'):
from calibre.utils.matcher import test
a(test(return_tests=True))
if ok('icu'):
from calibre.utils.icu_test import find_tests
a(find_tests())
if ok('smartypants'):
from calibre.utils.smartypants import run_tests
a(run_tests(return_tests=True))
if ok('ebooks'):
from calibre.ebooks.metadata.rtf import find_tests
a(find_tests())
from calibre.ebooks.metadata.html import find_tests
a(find_tests())
from calibre.utils.xml_parse import find_tests
a(find_tests())
from calibre.gui2.viewer.annotations import find_tests
a(find_tests())
if ok('misc'):
from calibre.ebooks.metadata.test_author_sort import find_tests
a(find_tests())
from calibre.ebooks.metadata.tag_mapper import find_tests
a(find_tests())
from calibre.ebooks.metadata.author_mapper import find_tests
a(find_tests())
from calibre.utils.shared_file import find_tests
a(find_tests())
from calibre.utils.test_lock import find_tests
a(find_tests())
from calibre.utils.search_query_parser_test import find_tests
a(find_tests())
from calibre.utils.html2text import find_tests
a(find_tests())
from calibre.library.comments import find_tests
a(find_tests())
from calibre.ebooks.compression.palmdoc import find_tests
a(find_tests())
from calibre.gui2.viewer.convert_book import find_tests
a(find_tests())
from calibre.utils.hyphenation.test_hyphenation import find_tests
a(find_tests())
from calibre.live import find_tests
a(find_tests())
if iswindows:
from calibre.utils.windows.wintest import find_tests
a(find_tests())
from calibre.utils.windows.winsapi import find_tests
a(find_tests())
a(unittest.defaultTestLoader.loadTestsFromTestCase(TestImports))
if ok('dbcli'):
from calibre.db.cli.tests import find_tests
a(find_tests())
tests = unittest.TestSuite(ans)
return tests
class Test(Command):
description = 'Run the calibre test suite'
def add_options(self, parser):
parser.add_option('--test-verbosity', type=int, default=4, help='Test verbosity (0-4)')
parser.add_option('--test-module', '--test-group', default=[], action='append', type='choice', choices=sorted(map(str, TEST_MODULES)),
help='The test module to run (can be specified more than once for multiple modules). Choices: %s' % ', '.join(sorted(TEST_MODULES)))
parser.add_option('--test-name', '-n', default=[], action='append',
help='The name of an individual test to run. Can be specified more than once for multiple tests. The name of the'
' test is the name of the test function without the leading test_. For example, the function test_something()'
' can be run by specifying the name "something".')
parser.add_option('--exclude-test-module', default=[], action='append', type='choice', choices=sorted(map(str, TEST_MODULES)),
help='A test module to be excluded from the test run (can be specified more than once for multiple modules).'
' Choices: %s' % ', '.join(sorted(TEST_MODULES)))
parser.add_option('--exclude-test-name', default=[], action='append',
help='The name of an individual test to be excluded from the test run. Can be specified more than once for multiple tests.')
parser.add_option('--under-sanitize', default=False, action='store_true',
help='Run the test suite with the sanitizer preloaded')
def run(self, opts):
if opts.under_sanitize and 'libasan' not in os.environ.get('LD_PRELOAD', ''):
os.environ['LD_PRELOAD'] = os.path.abspath(subprocess.check_output('gcc -print-file-name=libasan.so'.split()).decode('utf-8').strip())
os.environ['ASAN_OPTIONS'] = 'detect_leaks=0'
self.info(f'Re-execing with LD_PRELOAD={os.environ["LD_PRELOAD"]}')
sys.stdout.flush()
os.execl('setup.py', *sys.argv)
from calibre.utils.run_tests import (
filter_tests_by_name, remove_tests_by_name, run_cli
)
tests = find_tests(which_tests=frozenset(opts.test_module), exclude_tests=frozenset(opts.exclude_test_module))
if opts.test_name:
tests = filter_tests_by_name(tests, *opts.test_name)
if opts.exclude_test_name:
tests = remove_tests_by_name(tests, *opts.exclude_test_name)
run_cli(tests, verbosity=opts.test_verbosity)
class TestRS(Command):
description = 'Run tests for RapydScript code'
def run(self, opts):
from calibre.utils.rapydscript import run_rapydscript_tests
run_rapydscript_tests()