diff --git a/product/ERP5Type/Base.py b/product/ERP5Type/Base.py index bae63d72c44ddeac4e7a30e2efa3567c85837a31..67e41f18b3f8faeac6f8348effcea382927974bd 100644 --- a/product/ERP5Type/Base.py +++ b/product/ERP5Type/Base.py @@ -2924,23 +2924,39 @@ class Base( CopyContainer, dynamic_accessor_list.append(subdochelper) if getattr(documented_item, property['id'], None) is not None: dynamic_property_list.append(subdochelper) - if getattr(property_sheet, '_categories', None) is not None: - for category in property_sheet._categories: - if category in seen_categories: - continue - seen_categories.append(category) - subdochelper = newTempDocumentationHelper(dochelper, category, title=category, - content=pformat(documented_item.getCategoryMembershipList(category))) - subdochelper_dynamic_accessor_list = [] - for accessor_name in generateCategoryAccessorNameList(category): - accessor = getattr(item_class, accessor_name, getattr(documented_item, accessor_name, None)) - # First get it on the class, and if not on the instance, thereby among dynamic accessors. - if accessor is not None: - subdochelper_dynamic_accessor_list.append(accessorAsDocumentationHelper(accessor)) - subdochelper_dynamic_accessor_list.sort() - subdochelper.setDynamicAccessorList(subdochelper_dynamic_accessor_list) - dynamic_accessor_list.append(subdochelper) - dynamic_category_list.append(subdochelper) + + def visitCategory(category): + if category in seen_categories: + return + seen_categories.append(category) + subdochelper = newTempDocumentationHelper(dochelper, category, title=category, + content=pformat(documented_item.getCategoryMembershipList(category))) + subdochelper_dynamic_accessor_list = [] + for accessor_name in generateCategoryAccessorNameList(category): + accessor = getattr(item_class, accessor_name, getattr(documented_item, accessor_name, None)) + # First get it on the class, and if not on the instance, thereby among dynamic accessors. + if accessor is not None: + subdochelper_dynamic_accessor_list.append(accessorAsDocumentationHelper(accessor)) + subdochelper_dynamic_accessor_list.sort() + subdochelper.setDynamicAccessorList(subdochelper_dynamic_accessor_list) + dynamic_accessor_list.append(subdochelper) + dynamic_category_list.append(subdochelper) + + category_list = getattr(property_sheet, '_categories', []) + # some categories are defined by expressions, so we have to do 2 + # passes, a first one to treat regular category list and collect + # categories defined by expression, a second one to treat thoses + # new categories from expressions. + expression_category_list = [] + for category in category_list: + if isinstance(category, Expression): + econtext = createExpressionContext(self) + expression_category_list.extend(category(econtext)) + continue + visitCategory(category) + + for category in expression_category_list: + visitCategory(category) # KEEPME: usefull to track the differences between accessors defined on # PortalType and the one detected on the documented item. diff --git a/product/ERP5Type/tests/testClassTool.py b/product/ERP5Type/tests/testClassTool.py index 3db94bb158e9de48b243f711fe26d8be4d4fdec7..7a4d6344c0cf49d2dd6853bdb83ad84567ab5ba4 100644 --- a/product/ERP5Type/tests/testClassTool.py +++ b/product/ERP5Type/tests/testClassTool.py @@ -128,6 +128,28 @@ class TestClassTool(ERP5TypeTestCase): self.assertEquals(0, len(portal.portal_activities.getMessageList())) + def test_DocumentationHelperExpressionCategory(self): + # This tests checks that Documentation Helper works with propertysheets + # that define their categories using expressions. + from Products.ERP5Type.Document.Movement import Movement + from Products.CMFCore.Expression import Expression + movement = Movement('testing_id').__of__(self.getPortal()) + # This test relies on the fact that Movement class has categories defined + # by an expression. + category_list = [] + found_one = 0 + for ps in movement.property_sheets: + for category in getattr(ps, '_categories', []): + if isinstance(category, Expression): + found_one = 1 + if found_one: + break + else: + self.fail("Movement _categories doesn't include expressions; " + "this test is outdated") + self.assertNotEquals(None, movement.asDocumentationHelper()) + + import unittest def test_suite(): suite = unittest.TestSuite()