# ============================================================================
#
# Copyright (C) 2007-2011 Conceptive Engineering bvba. All rights reserved.
# www.conceptive.be / project-camelot@conceptive.be
#
# This file is part of the Camelot Library.
#
# This file may be used under the terms of the GNU General Public
# License version 2.0 as published by the Free Software Foundation
# and appearing in the file license.txt included in the packaging of
# this file. Please review this information to ensure GNU
# General Public Licensing requirements will be met.
#
# If you are unsure which license is appropriate for your use, please
# visit www.python-camelot.com or contact project-camelot@conceptive.be
#
# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# For use of this library in commercial applications, please contact
# project-camelot@conceptive.be
#
# ============================================================================
"""
Camelot unittest framework
"""
import unittest
_application_ = []
[docs]def get_application():
"""Get the singleton QApplication"""
from PyQt4.QtGui import QApplication
if not len(_application_):
#
# Uniform style for screenshot generation
#
QApplication.setStyle('cleanlooks')
application = QApplication.instance()
if not application:
import sys
from camelot.view import art
application = QApplication(sys.argv)
application.setStyleSheet( art.read('stylesheet/office2007_blue.qss') )
from PyQt4 import QtCore
QtCore.QLocale.setDefault( QtCore.QLocale('nl_BE') )
_application_.append( application )
return _application_[0]
[docs]class ModelThreadTestCase(unittest.TestCase):
"""Base class for implementing test cases that need a running model_thread.
"""
images_path = ''
[docs] def process(self):
"""Wait until all events are processed and the queues of the model thread are empty"""
self.mt.wait_on_work()
[docs] def setUp(self):
self.app = get_application()
from camelot.view import model_thread
from camelot.view.model_thread.no_thread_model_thread import NoThreadModelThread
from camelot.view.model_thread import get_model_thread, has_model_thread
from camelot.view.remote_signals import construct_signal_handler, has_signal_handler
if not has_model_thread():
#
# Run the tests without real threading, to avoid timing problems with screenshots etc.
#
model_thread._model_thread_.insert( 0, NoThreadModelThread() )
if not has_signal_handler():
construct_signal_handler()
self.mt = get_model_thread()
if not self.mt.isRunning():
self.mt.start()
# make sure the startup sequence has passed
self.process()
[docs] def tearDown(self):
self.process()
#self.mt.exit(0)
#self.mt.wait()
[docs]class SchemaTest(ModelThreadTestCase):
"""Test the database schema"""
[docs] def test_schema_display(self):
def schema_display_task():
import os
from camelot.bin.camelot_manage import schema_display
schema_display(os.path.join(self.images_path, 'schema.png'))
from camelot.view.model_thread import get_model_thread, post
post( schema_display_task )
get_model_thread().wait_on_work()
[docs]class ApplicationViewsTest(ModelThreadTestCase):
"""Test various application level views, like the main window, the
sidepanel"""
[docs] def get_application_admin(self):
"""Overwrite this method to make use of a custom application admin"""
from camelot.admin.application_admin import ApplicationAdmin
return ApplicationAdmin()
[docs] def test_navigation_pane(self):
from camelot.view.controls import navpane2
from PyQt4 import QtCore
translator = self.get_application_admin().get_translator()
QtCore.QCoreApplication.installTranslator(translator)
app_admin = self.get_application_admin()
nav_pane = navpane2.NavigationPane(app_admin, None, None)
self.grab_widget(nav_pane, subdir='applicationviews')
for i, section in enumerate(nav_pane.get_sections()):
nav_pane.change_current((i, unicode(section.get_verbose_name())))
self.grab_widget(nav_pane, suffix=section.get_name(), subdir='applicationviews')
[docs] def test_main_window(self):
from camelot.view.mainwindow import MainWindow
from PyQt4 import QtCore
translator = self.get_application_admin().get_translator()
QtCore.QCoreApplication.installTranslator(translator)
app_admin = self.get_application_admin()
widget = MainWindow(app_admin)
self.grab_widget(widget, subdir='applicationviews')
[docs]class EntityViewsTest(ModelThreadTestCase):
"""Test the views of all the Entity subclasses, subclass this class to test all views
in your application. This is done by calling the create_table_view and create_new_view
on a set of admin objects. To tell the test case which admin objects should be tested,
overwrite the get_admins method ::
class MyEntityViewsTest(EntityViewsTest):
def get_admins(self):
from elixir import entities
application_admin import MyApplicationAdmin
self.app_admin = MyApplicationAdmin()
return [self.app_admin.get_entity_admin(e) for e in entities if self.app_admin.get_entity_admin(e)]
"""
[docs] def setUp(self):
super(EntityViewsTest, self).setUp()
from PyQt4 import QtCore
translators = self.get_application_admin().get_translator()
for translator in translators:
QtCore.QCoreApplication.installTranslator(translator)
[docs] def get_application_admin(self):
"""Overwrite this method to make use of a custom application admin"""
from camelot.admin.application_admin import ApplicationAdmin
return ApplicationAdmin()
[docs] def get_admins(self):
"""Should return all admin for which a table and a form view should be displayed,
by default, returns for all entities their default admin"""
from sqlalchemy.orm.mapper import _mapper_registry
classes = []
for mapper in _mapper_registry.keys():
if hasattr(mapper, 'class_'):
classes.append( mapper.class_ )
else:
raise Exception()
app_admin = self.get_application_admin()
return [app_admin.get_entity_admin(c) for c in classes if app_admin.get_entity_admin(c)]
[docs] def test_select_view(self):
for admin in self.get_admins():
widget = admin.create_select_view()
self.grab_widget(widget, suffix=admin.entity.__name__.lower(), subdir='entityviews')
[docs] def test_table_view(self):
for admin in self.get_admins():
widget = admin.create_table_view()
self.grab_widget(widget, suffix=admin.entity.__name__.lower(), subdir='entityviews')
[docs] def test_new_view(self):
for admin in self.get_admins():
widget = admin.create_new_view()
self.grab_widget(widget, suffix=admin.entity.__name__.lower(), subdir='entityviews')