Commit ed0a92be authored by Arnaud Fontaine's avatar Arnaud Fontaine

Implement ZODB Test Component.

parent 5197e2c7
...@@ -3913,13 +3913,19 @@ class ExtensionTemplateItem(DocumentTemplateItem): ...@@ -3913,13 +3913,19 @@ class ExtensionTemplateItem(DocumentTemplateItem):
def getTemplateIdList(self): def getTemplateIdList(self):
return self.getTemplateExtensionIdList() return self.getTemplateExtensionIdList()
class TestTemplateItem(FilesystemDocumentTemplateItem): class TestTemplateItem(DocumentTemplateItem):
local_file_reader_name = staticmethod(readLocalTest) local_file_reader_name = staticmethod(readLocalTest)
local_file_writer_name = staticmethod(writeLocalTest) local_file_writer_name = staticmethod(writeLocalTest)
# Test needs no import # Test needs no import
local_file_importer_name = None local_file_importer_name = None
local_file_remover_name = staticmethod(removeLocalTest) local_file_remover_name = staticmethod(removeLocalTest)
@staticmethod
def _getZodbObjectId(id):
return 'erp5.component.test.' + id
def getTemplateIdList(self):
return self.getTemplateTestIdList()
class ProductTemplateItem(BaseTemplateItem): class ProductTemplateItem(BaseTemplateItem):
# XXX Not implemented yet # XXX Not implemented yet
...@@ -5814,6 +5820,21 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -5814,6 +5820,21 @@ Business Template is a set of definitions, such as skins, portal types and categ
self.setTemplateExtensionIdList(extension_id_list) self.setTemplateExtensionIdList(extension_id_list)
from Products.ERP5Type.Core.TestComponent import TestComponent
test_id_list = self.getTemplateTestIdList()
for i, reference in enumerate(test_id_list):
try:
obj = TestComponent.importFromFilesystem(component_tool,
reference,
version_priority,
erase_existing)
except Exception, e:
failed_import_dict[reference] = str(e)
else:
test_id_list[i] = obj.getId()
self.setTemplateTestIdList(test_id_list)
return failed_import_dict return failed_import_dict
# Block acquisition on all _item_name_list properties by setting # Block acquisition on all _item_name_list properties by setting
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
<portal_type id="Extension Component"> <portal_type id="Extension Component">
<item>SortIndex</item> <item>SortIndex</item>
</portal_type> </portal_type>
<portal_type id="Test Component">
<item>SortIndex</item>
</portal_type>
<portal_type id="Trash Bin"> <portal_type id="Trash Bin">
<item>Base</item> <item>Base</item>
<item>SimpleItem</item> <item>SimpleItem</item>
......
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
</item> </item>
<item> <item>
<key> <string>type_class</string> </key> <key> <string>type_class</string> </key>
<value> <string>Component</string> </value> <value> <string>TestComponent</string> </value>
</item> </item>
<item> <item>
<key> <string>type_interface</string> </key> <key> <string>type_interface</string> </key>
......
...@@ -143,4 +143,8 @@ ...@@ -143,4 +143,8 @@
<type>TALES Constraint</type> <type>TALES Constraint</type>
<workflow>dynamic_class_generation_interaction_workflow</workflow> <workflow>dynamic_class_generation_interaction_workflow</workflow>
</chain> </chain>
<chain>
<type>Test Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain>
</workflow_chain> </workflow_chain>
\ No newline at end of file
...@@ -52,12 +52,11 @@ ...@@ -52,12 +52,11 @@
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>template_document_id_list = context.getTemplateDocumentIdList()\n <value> <string>template_document_id_list = context.getTemplateDocumentIdList()\n
template_extension_id_list = context.getTemplateExtensionIdList()\n template_extension_id_list = context.getTemplateExtensionIdList()\n
if not (template_document_id_list or template_extension_id_list):\n template_test_id_list = context.getTemplateTestIdList()\n
if not (template_document_id_list or template_extension_id_list or template_test_id_list):\n
return []\n return []\n
\n \n
migrated_component_id_list = template_document_id_list + template_extension_id_list\n component_tool = context.getPortalObject().portal_components\n
portal = context.getPortalObject()\n
component_tool = portal.portal_components\n
\n \n
from Products.ERP5Type.Document import newTempBase\n from Products.ERP5Type.Document import newTempBase\n
def addLineListByType(id_list, destination_portal_type, line_list):\n def addLineListByType(id_list, destination_portal_type, line_list):\n
...@@ -76,6 +75,7 @@ def addLineListByType(id_list, destination_portal_type, line_list):\n ...@@ -76,6 +75,7 @@ def addLineListByType(id_list, destination_portal_type, line_list):\n
line_list = []\n line_list = []\n
addLineListByType(template_document_id_list, \'Document Component\', line_list)\n addLineListByType(template_document_id_list, \'Document Component\', line_list)\n
addLineListByType(template_extension_id_list, \'Extension Component\', line_list)\n addLineListByType(template_extension_id_list, \'Extension Component\', line_list)\n
addLineListByType(template_test_id_list, \'Test Component\', line_list)\n
return line_list\n return line_list\n
</string> </value> </string> </value>
</item> </item>
......
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
<list> <list>
<string>Document Component</string> <string>Document Component</string>
<string>Extension Component</string> <string>Extension Component</string>
<string>Test Component</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
<list> <list>
<string>Document Component</string> <string>Document Component</string>
<string>Extension Component</string> <string>Extension Component</string>
<string>Test Component</string>
</list> </list>
</value> </value>
</item> </item>
......
2012-03-02 arnaud.fontaine
* Implement Test Component.
2012-03-02 arnaud.fontaine 2012-03-02 arnaud.fontaine
* Do not acquire local roles for Document Component Portal Type. * Do not acquire local roles for Document Component Portal Type.
......
41023 41024
\ No newline at end of file \ No newline at end of file
Document Component | SortIndex Document Component | SortIndex
Extension Component | SortIndex Extension Component | SortIndex
Test Component | SortIndex
Trash Bin | Base Trash Bin | Base
Trash Bin | SimpleItem Trash Bin | SimpleItem
Trash Bin | Task Trash Bin | Task
\ No newline at end of file
...@@ -40,4 +40,7 @@ Property Type Validity Constraint | dynamic_class_generation_interaction_workflo ...@@ -40,4 +40,7 @@ Property Type Validity Constraint | dynamic_class_generation_interaction_workflo
Standard Property | dynamic_class_generation_interaction_workflow Standard Property | dynamic_class_generation_interaction_workflow
String Attribute Match Constraint | dynamic_class_generation_interaction_workflow String Attribute Match Constraint | dynamic_class_generation_interaction_workflow
System Preference | preference_workflow System Preference | preference_workflow
TALES Constraint | dynamic_class_generation_interaction_workflow TALES Constraint | dynamic_class_generation_interaction_workflow
\ No newline at end of file Test Component | component_validation_workflow
Test Component | dynamic_class_generation_interaction_workflow
Test Component | edit_workflow
\ No newline at end of file
...@@ -6928,7 +6928,7 @@ class TestDocumentTemplateItem(BusinessTemplateMixin): ...@@ -6928,7 +6928,7 @@ class TestDocumentTemplateItem(BusinessTemplateMixin):
other one is the metadata (ending with '.xml') other one is the metadata (ending with '.xml')
""" """
component_bt_tool_path = os.path.join(sequence['template_path'], component_bt_tool_path = os.path.join(sequence['template_path'],
self.__class__.__name__.replace('Test', ''), self.__class__.__name__[len('Test'):],
'portal_components') 'portal_components')
self.assertTrue(os.path.exists(component_bt_tool_path)) self.assertTrue(os.path.exists(component_bt_tool_path))
...@@ -7203,6 +7203,8 @@ class TestExtensionTemplateItem(TestDocumentTemplateItem): ...@@ -7203,6 +7203,8 @@ class TestExtensionTemplateItem(TestDocumentTemplateItem):
importFromFilesystem = ExtensionComponent.importFromFilesystem importFromFilesystem = ExtensionComponent.importFromFilesystem
set_template_id_method_name = 'setTemplateExtensionId' set_template_id_method_name = 'setTemplateExtensionId'
from Products.ERP5Type.Core.TestComponent import TestComponent
class TestTestTemplateItem(TestDocumentTemplateItem): class TestTestTemplateItem(TestDocumentTemplateItem):
document_title = 'UnitTest' document_title = 'UnitTest'
document_data = """class UnitTest: document_data = """class UnitTest:
...@@ -7216,6 +7218,12 @@ class TestTestTemplateItem(TestDocumentTemplateItem): ...@@ -7216,6 +7218,12 @@ class TestTestTemplateItem(TestDocumentTemplateItem):
document_base_path = os.path.join(getConfiguration().instancehome, 'tests') document_base_path = os.path.join(getConfiguration().instancehome, 'tests')
template_property = 'template_test_id_list' template_property = 'template_test_id_list'
# Specific to ZODB Extension Component
component_module = TestComponent._getDynamicModuleNamespace()
component_portal_type = TestComponent.portal_type
importFromFilesystem = TestComponent.importFromFilesystem
set_template_id_method_name = 'setTemplateTestId'
def stepAddTestToBusinessTemplate(self, sequence=None, **kw): def stepAddTestToBusinessTemplate(self, sequence=None, **kw):
bt = sequence['current_bt'] bt = sequence['current_bt']
bt.edit(template_test_id_list=[sequence['test_title']]) bt.edit(template_test_id_list=[sequence['test_title']])
...@@ -7298,18 +7306,9 @@ class TestTestTemplateItem(TestDocumentTemplateItem): ...@@ -7298,18 +7306,9 @@ class TestTestTemplateItem(TestDocumentTemplateItem):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# XXX-arnau: Skip until ZODB Tests and Constraints have been implemented (not # XXX-arnau: Skip until ZODB Constraints have been implemented (not
# expectedFailure because following tests would fail after the ZODB Component # expectedFailure because following tests would fail after the ZODB Component
# has been created) # has been created)
TestTestTemplateItem.test_BusinessTemplateWithZodbDocument = skip(
'Not implemented yet')(TestTestTemplateItem.test_BusinessTemplateWithZodbDocument)
TestTestTemplateItem.test_BusinessTemplateWithZodbDocumentNonExistingBefore = \
skip('Not implemented yet')(TestTestTemplateItem.test_BusinessTemplateWithZodbDocumentNonExistingBefore)
TestTestTemplateItem.test_BusinessTemplateWithZodbDocumentMigrated = \
skip('Not implemented yet')(TestTestTemplateItem.test_BusinessTemplateWithZodbDocumentMigrated)
TestConstraintTemplateItem.test_BusinessTemplateWithZodbDocument = skip( TestConstraintTemplateItem.test_BusinessTemplateWithZodbDocument = skip(
'Not implemented yet')(TestConstraintTemplateItem.test_BusinessTemplateWithZodbDocument) 'Not implemented yet')(TestConstraintTemplateItem.test_BusinessTemplateWithZodbDocument)
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved.
# Arnaud Fontaine <arnaud.fontaine@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# 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; either version 2
# of the License, or (at your option) any later version.
#
# 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from Products.ERP5Type.mixin.component import ComponentMixin
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
import zope.interface
from Products.ERP5Type.interfaces.component import IComponent
class TestComponent(ComponentMixin):
# CMF Type Definition
meta_type = 'ERP5 Test Component'
portal_type = 'Test Component'
zope.interface.implements(IComponent)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
@staticmethod
def _getFilesystemPath():
import os.path
from App.config import getConfiguration
return os.path.join(getConfiguration().instancehome, 'tests')
@staticmethod
def _getDynamicModuleNamespace():
return 'erp5.component.test'
...@@ -41,6 +41,10 @@ from Products.ERP5Type.TransactionalVariable import getTransactionalVariable ...@@ -41,6 +41,10 @@ from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from zLOG import LOG, INFO, WARNING from zLOG import LOG, INFO, WARNING
from DateTime import DateTime
DEFAULT_TEST_TEMPLATE_COPYRIGHT = "Copyright (c) 2002-%s Nexedi SA and " \
"Contributors. All Rights Reserved." % DateTime().year()
last_sync = -1 last_sync = -1
class ComponentTool(BaseTool): class ComponentTool(BaseTool):
""" """
...@@ -117,3 +121,80 @@ class ComponentTool(BaseTool): ...@@ -117,3 +121,80 @@ class ComponentTool(BaseTool):
tv[key] = None tv[key] = None
transaction.get().addBeforeCommitHook(self.reset, transaction.get().addBeforeCommitHook(self.reset,
args=(True, True)) args=(True, True))
# XXX-arnau: copy/paste from ClassTool
__test_text_content_template = '''\
##############################################################################
#
# %s
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# 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; either version 2
# of the License, or (at your option) any later version.
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
class Test(ERP5TypeTestCase):
"""
A Sample Test Class
"""
def getTitle(self):
return "SampleTest"
def getBusinessTemplateList(self):
"""
Tuple of Business Templates we need to install
"""
return ('erp5_base',)
def afterSetUp(self):
"""
This is ran before anything, used to set the environment
"""
# here, you can create the categories and objects your test will depend on
pass
def test_01_sampleTest(self):
"""
A Sample Test
For the method to be called during the test,
its name must start with 'test'.
The '_01_' part of the name is not mandatory,
it just allows you to define in which order the tests are to be launched.
Tests methods (self.assert... and self.failIf...)
are defined in /usr/lib/python/unittest.py.
"""
self.assertEqual(0, 1)
''' % DEFAULT_TEST_TEMPLATE_COPYRIGHT
def newContent(self, *args, **kwargs):
"""
Create new content. If this is a Test Component and no text_content has
been given, then define a default template to help user, likewise
ClassTool with filesystem live tests
"""
if kwargs.get('portal_type') == 'Test Component':
kwargs.setdefault('text_content', self.__test_text_content_template)
return super(ComponentTool, self).newContent(*args, **kwargs)
...@@ -132,3 +132,6 @@ def initializeDynamicModules(): ...@@ -132,3 +132,6 @@ def initializeDynamicModules():
erp5.component.document = ComponentDynamicPackage('erp5.component.document', erp5.component.document = ComponentDynamicPackage('erp5.component.document',
'Document Component') 'Document Component')
erp5.component.test = ComponentDynamicPackage('erp5.component.test',
'Test Component')
...@@ -128,6 +128,7 @@ class ERP5TypeLiveTestCase(ERP5TypeTestCaseMixin): ...@@ -128,6 +128,7 @@ class ERP5TypeLiveTestCase(ERP5TypeTestCaseMixin):
'''Returns the app object for a test.''' '''Returns the app object for a test.'''
return self.getPortal().aq_parent return self.getPortal().aq_parent
from Products.ERP5Type.dynamic.component_package import ComponentDynamicPackage
from Products.ERP5Type.tests.runUnitTest import ERP5TypeTestLoader from Products.ERP5Type.tests.runUnitTest import ERP5TypeTestLoader
class ERP5TypeTestReLoader(ERP5TypeTestLoader): class ERP5TypeTestReLoader(ERP5TypeTestLoader):
...@@ -155,14 +156,39 @@ class ERP5TypeTestReLoader(ERP5TypeTestLoader): ...@@ -155,14 +156,39 @@ class ERP5TypeTestReLoader(ERP5TypeTestLoader):
if self.filter_test_list: if self.filter_test_list:
ERP5TypeTestLoader.filter_test_list = old_filter_test_list ERP5TypeTestLoader.filter_test_list = old_filter_test_list
def loadTestsFromName(self, name, module=None):
"""
Load the test from the given name from ZODB if it can be imported,
otherwise fallback on filesystem
"""
if module is None:
import erp5.component.test
try:
module = __import__('erp5.component.test.' + name,
fromlist=['erp5.component.test'],
level=0)
except ImportError:
pass
return super(ERP5TypeTestReLoader, self).loadTestsFromName(name,
module)
def loadTestsFromModule(self, module): def loadTestsFromModule(self, module):
reload(module) """
If the module is not a ZODB Component, then reload it to consider
modifications on the filesystem
"""
if not instance(module, ComponentDynamicPackage):
reload(module)
return super(ERP5TypeTestReLoader, self).loadTestsFromModule(module) return super(ERP5TypeTestReLoader, self).loadTestsFromModule(module)
def loadTestsFromTestCase(self, testCaseClass): def loadTestsFromTestCase(self, testCaseClass):
testModule = sys.modules[testCaseClass.__module__] testModule = sys.modules[testCaseClass.__module__]
if not(testCaseClass is ERP5TypeTestCase): # Do not reload ERP5TypeTestCase because we patch it nor ZODB Test
# do not reload ERP5TypeTestCase because we patch it # Component as it is reset upon modification anyway
if (testCaseClass is not ERP5TypeTestCase and
not isinstance(testModule, ComponentDynamicPackage)):
testModule = reload(testModule) testModule = reload(testModule)
testCaseClass = getattr(testModule, testCaseClass.__name__) testCaseClass = getattr(testModule, testCaseClass.__name__)
return ERP5TypeTestLoader.loadTestsFromTestCase(self, testCaseClass) return ERP5TypeTestLoader.loadTestsFromTestCase(self, testCaseClass)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment