Bible database tests

This commit is contained in:
Tim Bentley 2014-03-11 19:01:09 +00:00
parent 776724d9a2
commit a74567b9f6
10 changed files with 297 additions and 116 deletions

View File

@ -82,11 +82,8 @@ def upgrade_db(url, upgrade):
"""
Upgrade a database.
``url``
The url of the database to upgrade.
``upgrade``
The python module that contains the upgrade instructions.
:param url: The url of the database to upgrade.
:param upgrade: The python module that contains the upgrade instructions.
"""
session, metadata = init_db(url)
@ -99,7 +96,7 @@ def upgrade_db(url, upgrade):
metadata_table = Table('metadata', metadata,
Column('key', types.Unicode(64), primary_key=True),
Column('value', types.UnicodeText(), default=None)
)
)
metadata_table.create(checkfirst=True)
mapper(Metadata, metadata_table)
version_meta = session.query(Metadata).get('version')
@ -137,11 +134,8 @@ def delete_database(plugin_name, db_file_name=None):
"""
Remove a database file from the system.
``plugin_name``
The name of the plugin to remove the database for
``db_file_name``
The database file name. Defaults to None resulting in the plugin_name being used.
:param plugin_name: The name of the plugin to remove the database for
:param db_file_name: The database file name. Defaults to None resulting in the plugin_name being used.
"""
db_file_path = None
if db_file_name:
@ -175,17 +169,11 @@ class Manager(object):
Runs the initialisation process that includes creating the connection to the database and the tables if they do
not exist.
``plugin_name``
The name to setup paths and settings section names
``init_schema``
The init_schema function for this database
``upgrade_schema``
The upgrade_schema function for this database
``db_file_name``
The file name to use for this database. Defaults to None resulting in the plugin_name being used.
:param plugin_name: The name to setup paths and settings section names
:param init_schema: The init_schema function for this database
:param db_file_name: The upgrade_schema function for this database
:param upgrade_mod: The file name to use for this database. Defaults to None resulting in the plugin_name
being used.
"""
settings = Settings()
settings.beginGroup(plugin_name)
@ -208,7 +196,10 @@ class Manager(object):
self.db_url += '?charset=%s' % urlquote(db_encoding)
settings.endGroup()
if upgrade_mod:
db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod)
try:
db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod)
except (SQLAlchemyError, DBAPIError):
log.exception('Error loading database: %s', self.db_url)
if db_ver > up_ver:
critical_error_message_box(
translate('OpenLP.Manager', 'Database Error'),
@ -229,11 +220,8 @@ class Manager(object):
"""
Save an object to the database
``object_instance``
The object to save
``commit``
Commit the session with this object
:param object_instance: The object to save
:param commit: Commit the session with this object
"""
for try_count in range(3):
try:
@ -262,11 +250,8 @@ class Manager(object):
"""
Save a list of objects to the database
``object_list``
The list of objects to save
``commit``
Commit the session with this object
:param object_list: The list of objects to save
:param commit: Commit the session with this object
"""
for try_count in range(3):
try:
@ -295,11 +280,8 @@ class Manager(object):
"""
Return the details of an object
``object_class``
The type of object to return
``key``
The unique reference or primary key for the instance to return
:param object_class: The type of object to return
:param key: The unique reference or primary key for the instance to return
"""
if not key:
return object_class()
@ -319,11 +301,8 @@ class Manager(object):
"""
Returns an object matching specified criteria
``object_class``
The type of object to return
``filter_clause``
The criteria to select the object by
:param object_class: The type of object to return
:param filter_clause: The criteria to select the object by
"""
for try_count in range(3):
try:
@ -340,14 +319,9 @@ class Manager(object):
"""
Returns all the objects from the database
``object_class``
The type of objects to return
``filter_clause``
The filter governing selection of objects to return. Defaults to None.
``order_by_ref``
Any parameters to order the returned objects by. Defaults to None.
:param object_class: The type of objects to return
:param filter_clause: The filter governing selection of objects to return. Defaults to None.
:param order_by_ref: Any parameters to order the returned objects by. Defaults to None.
"""
query = self.session.query(object_class)
if filter_clause is not None:
@ -371,11 +345,8 @@ class Manager(object):
"""
Returns a count of the number of objects in the database.
``object_class``
The type of objects to return.
``filter_clause``
The filter governing selection of objects to return. Defaults to None.
:param object_class: The type of objects to return.
:param filter_clause: The filter governing selection of objects to return. Defaults to None.
"""
query = self.session.query(object_class)
if filter_clause is not None:
@ -395,11 +366,8 @@ class Manager(object):
"""
Delete an object from the database
``object_class``
The type of object to delete
``key``
The unique reference or primary key for the instance to be deleted
:param object_class: The type of object to delete
:param key: The unique reference or primary key for the instance to be deleted
"""
if key != 0:
object_instance = self.get_object(object_class, key)
@ -432,11 +400,8 @@ class Manager(object):
Delete all object records. This method should only be used for simple tables and **not** ones with
relationships. The relationships are not deleted from the database and this will lead to database corruptions.
``object_class``
The type of object to delete
``filter_clause``
The filter governing selection of objects to return. Defaults to None.
:param object_class: The type of object to delete
:param filter_clause: The filter governing selection of objects to return. Defaults to None.
"""
for try_count in range(3):
try:

View File

@ -182,9 +182,10 @@ def update_reference_separators():
"""
Updates separators and matches for parsing and formating scripture references.
"""
default_separators = translate('BiblesPlugin',
':|v|V|verse|verses;;-|to;;,|and;;end Double-semicolon delimited separators for parsing references. '
'Consult the developers for further information.').split(';;')
default_separators = \
translate('BiblesPlugin',
':|v|V|verse|verses;;-|to;;,|and;;end Double-semicolon delimited separators for parsing references. '
'Consult the developers for further information.').split(';;')
settings = Settings()
settings.beginGroup('bibles')
custom_separators = [
@ -206,8 +207,7 @@ def update_reference_separators():
for character in '\\.^$*+?{}[]()':
source_string = source_string.replace(character, '\\' + character)
# add various unicode alternatives
source_string = source_string.replace('-',
'(?:[-\u00AD\u2010\u2011\u2012\u2014\u2014\u2212\uFE63\uFF0D])')
source_string = source_string.replace('-', '(?:[-\u00AD\u2010\u2011\u2012\u2014\u2014\u2212\uFE63\uFF0D])')
source_string = source_string.replace(',', '(?:[,\u201A])')
REFERENCE_SEPARATORS['sep_%s' % role] = '\s*(?:%s)\s*' % source_string
REFERENCE_SEPARATORS['sep_%s_default' % role] = default_separators[index]
@ -227,8 +227,7 @@ def get_reference_separator(separator_type):
"""
Provides separators for parsing and formatting scripture references.
``separator_type``
The role and format of the separator.
:param separator_type: The role and format of the separator.
"""
if not REFERENCE_SEPARATORS:
update_reference_separators()
@ -239,8 +238,7 @@ def get_reference_match(match_type):
"""
Provides matches for parsing scripture references strings.
``match_type``
The type of match is ``range_separator``, ``range`` or ``full``.
:param match_type: The type of match is ``range_separator``, ``range`` or ``full``.
"""
if not REFERENCE_MATCHES:
update_reference_separators()
@ -410,15 +408,9 @@ class SearchResults(object):
"""
Create the search result object.
``book``
The book of the Bible.
``chapter``
The chapter of the book.
``verse_list``
The list of verses for this reading.
:param book: The book of the Bible.
:param chapter: The chapter of the book.
:param verse_list: The list of verses for this reading.
"""
self.book = book
self.chapter = chapter

View File

@ -48,6 +48,7 @@ log = logging.getLogger(__name__)
RESERVED_CHARACTERS = '\\.^$*+?{}[]()'
class BibleMeta(BaseModel):
"""
Bible Meta Data
@ -117,9 +118,8 @@ def init_schema(url):
class BibleDB(QtCore.QObject, Manager):
"""
This class represents a database-bound Bible. It is used as a base class
for all the custom importers, so that the can implement their own import
methods, but benefit from the database methods in here via inheritance,
This class represents a database-bound Bible. It is used as a base class for all the custom importers, so that
the can implement their own import methods, but benefit from the database methods in here via inheritance,
rather than depending on yet another object.
"""
log.info('BibleDB loaded')
@ -129,14 +129,13 @@ class BibleDB(QtCore.QObject, Manager):
The constructor loads up the database and creates and initialises the
tables if the database doesn't exist.
**Required keyword arguments:**
:param parent:
:param kwargs:
``path``
The path to the bible database file.
``path``
The path to the bible database file.
``name``
The name of the database. This is also used as the file name for
SQLite databases.
``name``
The name of the database. This is also used as the file name for SQLite databases.
"""
log.info('BibleDB loaded')
QtCore.QObject.__init__(self)
@ -178,9 +177,8 @@ class BibleDB(QtCore.QObject, Manager):
def register(self, wizard):
"""
This method basically just initialialises the database. It is called
from the Bible Manager when a Bible is imported. Descendant classes
may want to override this method to supply their own custom
This method basically just initialises the database. It is called from the Bible Manager when a Bible is
imported. Descendant classes may want to override this method to supply their own custom
initialisation as well.
:param wizard: The actual Qt wizard form.
@ -422,13 +420,11 @@ class BibleDB(QtCore.QObject, Manager):
log.debug('BibleDB.verse_search("%s")', text)
verses = self.session.query(Verse)
if text.find(',') > -1:
keywords = \
['%%%s%%' % keyword.strip() for keyword in text.split(',')]
keywords = ['%%%s%%' % keyword.strip() for keyword in text.split(',')]
or_clause = [Verse.text.like(keyword) for keyword in keywords]
verses = verses.filter(or_(*or_clause))
else:
keywords = \
['%%%s%%' % keyword.strip() for keyword in text.split(' ')]
keywords = ['%%%s%%' % keyword.strip() for keyword in text.split(' ')]
for keyword in keywords:
verses = verses.filter(Verse.text.like(keyword))
verses = verses.all()

View File

@ -58,8 +58,7 @@ class BibleFormat(object):
"""
Return the appropriate implementation class.
``format``
The Bible format.
:param format: The Bible format.
"""
if format == BibleFormat.OSIS:
return OSISBible
@ -93,9 +92,8 @@ class BibleManager(object):
def __init__(self, parent):
"""
Finds all the bibles defined for the system and creates an interface
object for each bible containing connection information. Throws
Exception if no Bibles are found.
Finds all the bibles defined for the system and creates an interface object for each bible containing
connection information. Throws Exception if no Bibles are found.
Init confirms the bible exists and stores the database path.
"""
@ -113,9 +111,8 @@ class BibleManager(object):
def reload_bibles(self):
"""
Reloads the Bibles from the available Bible databases on disk. If a web
Bible is encountered, an instance of HTTPBible is loaded instead of the
BibleDB class.
Reloads the Bibles from the available Bible databases on disk. If a web Bible is encountered, an instance
of HTTPBible is loaded instead of the BibleDB class.
"""
log.debug('Reload bibles')
files = AppLocation.get_files(self.settings_section, self.suffix)
@ -276,9 +273,9 @@ class BibleManager(object):
)
return None
language_selection = self.get_language_selection(bible)
reflist = parse_reference(verse_text, self.db_cache[bible], language_selection, book_ref_id)
if reflist:
return self.db_cache[bible].get_verses(reflist, show_error)
ref_list = parse_reference(verse_text, self.db_cache[bible], language_selection, book_ref_id)
if ref_list:
return self.db_cache[bible].get_verses(ref_list, show_error)
else:
if show_error:
reference_separators = {
@ -343,10 +340,10 @@ class BibleManager(object):
return None
# Check if the bible or second_bible is a web bible.
web_bible = self.db_cache[bible].get_object(BibleMeta, 'download_source')
second_webbible = ''
second_web_bible = ''
if second_bible:
second_webbible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
if web_bible or second_webbible:
second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
if web_bible or second_web_bible:
self.main_window.information_message(
translate('BiblesPlugin.BibleManager', 'Web Bible cannot be used'),
translate('BiblesPlugin.BibleManager', 'Text Search is not available with Web Bibles.')

View File

@ -1 +1,28 @@
__author__ = 'tim'
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################

View File

@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Package to test the openlp.plugin.bible.lib.https package.
"""

View File

@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Functional tests to test the Bible Manager class and related methods.
"""
import os
from tempfile import mkstemp
from unittest import TestCase
from openlp.core.common import Registry, Settings
from openlp.plugins.bibles.lib import BibleManager, LanguageSelection
from tests.interfaces import MagicMock, patch
from tests.utils.constants import TEST_RESOURCES_PATH
class TestBibleManager(TestCase):
def setUp(self):
"""
Set up the environment for testing bible queries with 1 Timothy 3
"""
fd, self.ini_file = mkstemp('.ini')
Settings().set_filename(self.ini_file)
Registry.create()
Registry().register('service_list', MagicMock())
Registry().register('application', MagicMock())
bible_settings = {
'bibles/proxy name': '',
'bibles/db type': 'sqlite',
'bibles/book name language': LanguageSelection.Bible,
'bibles/verse separator': '',
'bibles/range separator': '',
'bibles/list separator': '',
'bibles/end separator': '',
}
Settings().extend_default_settings(bible_settings)
with patch('openlp.core.common.applocation.Settings') as mocked_class, \
patch('openlp.core.common.AppLocation.get_section_data_path') as mocked_get_section_data_path, \
patch('openlp.core.common.AppLocation.get_files') as mocked_get_files:
# GIVEN: A mocked out Settings class and a mocked out AppLocation.get_files()
mocked_settings = mocked_class.return_value
mocked_settings.contains.return_value = False
mocked_get_files.return_value = ["tests.sqlite"]
mocked_get_section_data_path.return_value = TEST_RESOURCES_PATH + "/bibles"
self.manager = BibleManager(MagicMock())
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
os.unlink(self.ini_file)
def get_books_test(self):
"""
Test the get_books method
"""
# GIVEN given a bible in the bible manager
# WHEN asking for the books of the bible
books = self.manager.get_books('tests')
# THEN a list of books should be returned
self.assertEqual(66, len(books), 'There should be 66 books in the bible')
def get_book_by_id_test(self):
"""
Test the get_book_by_id method
"""
# GIVEN given a bible in the bible manager
# WHEN asking for the book of the bible
book = self.manager.get_book_by_id('tests', 54)
# THEN a book should be returned
self.assertEqual('1 Timothy', book.name, '1 Timothy should have been returned from the bible')
def get_chapter_count_test(self):
"""
Test the get_chapter_count method
"""
# GIVEN given a bible in the bible manager
# WHEN asking for the chapters in a book of the bible
book = self.manager.get_book_by_id('tests', 54)
chapter = self.manager.get_chapter_count('tests', book)
# THEN the chapter count should be returned
self.assertEqual(6, chapter, '1 Timothy should have 6 chapters returned from the bible')
def get_verse_count_by_book_ref_id_test(self):
"""
Test the get_verse_count_by_book_ref_id method
"""
# GIVEN given a bible in the bible manager
# WHEN asking for the number of verses in a book of the bible
verses = self.manager.get_verse_count_by_book_ref_id('tests', 54, 3)
# THEN the chapter count should be returned
self.assertEqual(16, verses, '1 Timothy v3 should have 16 verses returned from the bible')

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################

View File

@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Module to test the EditCustomForm.
"""

Binary file not shown.