diff --git a/CHANGES.rst b/CHANGES.rst index c4617c05..b8d1174d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -16,6 +16,9 @@ Changelog - Add conditional tests in content_type [kakshay21] +- Improve DX CT name normalization and question info, added more tests for DX CT normalization + [MrTango] + 3.3.0 (2018-05-24) ------------------ @@ -168,7 +171,7 @@ Changelog - Fixed the pypi index to explicitly reference https://pypi.python.org/simple/ to prevent buildout from defaulting to the old and unsupported http:// url. [pigeonflight] - + - Fix coveralls for packages created with addon and theme_package by converting the pickle output of createcoverage in .coverage to json. [pbauer] diff --git a/bobtemplates/plone/content_type.py b/bobtemplates/plone/content_type.py index f3a50474..3a1c089f 100644 --- a/bobtemplates/plone/content_type.py +++ b/bobtemplates/plone/content_type.py @@ -9,6 +9,7 @@ from mrbob.bobexceptions import SkipQuestion from mrbob.bobexceptions import ValidationError +import case_conversion as cc import keyword import os import re @@ -23,10 +24,13 @@ def is_container(configurator, question): def check_dexterity_type_name(configurator, question, answer): """Test if type name is valid.""" if keyword.iskeyword(answer): - raise ValidationError(u'{key} is a reserved Python keyword'.format(key=answer)) # NOQA: E501 + raise ValidationError(u'"{key}" is a reserved Python keyword!'.format(key=answer)) # NOQA: E501 if not re.match('[_a-zA-Z ]*$', answer): - raise ValidationError(u'{key} is not a valid identifier'.format(key=answer)) # NOQA: E501 - return answer + raise ValidationError( + u'"{key}" is not a valid identifier!\n' + u'Allowed characters: _ a-z A-Z and whitespace.\n'.format(key=answer), # NOQA: E501 + ) + return answer def check_global_allow(configurator, answer): @@ -238,13 +242,14 @@ def prepare_renderer(configurator): configurator = base_prepare_renderer(configurator) configurator.variables['template_id'] = 'content_type' type_name = configurator.variables['dexterity_type_name'] - configurator.variables[ - 'dexterity_type_name_klass'] = type_name.title().replace(' ', '') - configurator.variables[ - 'dexterity_type_name_fti'] = type_name.replace(' ', '_') - configurator.variables[ - 'dexterity_type_name_normalized'] = configurator.variables[ - 'dexterity_type_name_fti'].lower() + dx_type_name_klass = cc.pascalcase( + type_name, + ) + configurator.variables['dexterity_type_name_klass'] = dx_type_name_klass + dx_type_fti_file_name = type_name.replace(' ', '_') + configurator.variables['dexterity_type_fti_file_name'] = dx_type_fti_file_name # NOQA: E501 + dx_type_name_normalized = cc.snakecase(dx_type_fti_file_name) + configurator.variables['dexterity_type_name_normalized'] = dx_type_name_normalized # NOQA: E501 configurator.target_directory = configurator.variables['package_folder'] diff --git a/bobtemplates/plone/content_type/.mrbob.ini b/bobtemplates/plone/content_type/.mrbob.ini index 0891e44d..d20c7bd1 100644 --- a/bobtemplates/plone/content_type/.mrbob.ini +++ b/bobtemplates/plone/content_type/.mrbob.ini @@ -7,8 +7,8 @@ subtemplate_warning.post_ask_question = mrbob.hooks:validate_choices bobtemplate subtemplate_warning.choices = y|n subtemplate_warning.choices_delimiter = | -dexterity_type_name.question = Content type name -dexterity_type_name.help = Should be something like 'Todo Task' (no special characters!) +dexterity_type_name.question = Content type name (Allowed: _ a-z A-Z and whitespace) +dexterity_type_name.help = Should be something like 'Todo Task', avoid something like this 'TODOTask' dexterity_type_name.required = True dexterity_type_name.default = Todo Task dexterity_type_name.pre_ask_question = bobtemplates.plone.base:check_root_folder diff --git a/bobtemplates/plone/content_type/profiles/default/types/+dexterity_type_name_fti+.xml.bob b/bobtemplates/plone/content_type/profiles/default/types/+dexterity_type_fti_file_name+.xml.bob similarity index 100% rename from bobtemplates/plone/content_type/profiles/default/types/+dexterity_type_name_fti+.xml.bob rename to bobtemplates/plone/content_type/profiles/default/types/+dexterity_type_fti_file_name+.xml.bob diff --git a/package-tests/test_content_type.py b/package-tests/test_content_type.py index 54158b07..f003f5bc 100644 --- a/package-tests/test_content_type.py +++ b/package-tests/test_content_type.py @@ -63,7 +63,7 @@ def test_is_container_true(): content_type.is_container(configurator, None) -def test_prepare_renderer(): +def test_prepare_renderer(tmpdir): """Test prepare renderer.""" configurator = Configurator( template='bobtemplates.plone:content_type', @@ -72,10 +72,66 @@ def test_prepare_renderer(): 'non_interactive': True, }, variables={ - 'dexterity_type_name': 'Task', + 'dexterity_type_name': 'Special Task', + }, + ) + content_type.prepare_renderer(configurator) + assert configurator.variables['dexterity_type_name'] == 'Special Task' + assert configurator.variables['dexterity_type_fti_file_name'] == 'Special_Task' # NOQA: E501 + assert configurator.variables['dexterity_type_name_klass'] == 'SpecialTask' + assert configurator.variables['dexterity_type_name_normalized'] == 'special_task' # NOQA: E501 + assert configurator.target_directory.endswith('/collective.todo/src/collective/todo') # NOQA: E501 + + configurator = Configurator( + template='bobtemplates.plone:content_type', + target_directory='collective.foo.bar', + bobconfig={ + 'non_interactive': True, + }, + variables={ + 'dexterity_type_name': 'SpecialTask', + }, + ) + content_type.prepare_renderer(configurator) + assert configurator.variables['dexterity_type_name'] == 'SpecialTask' + assert configurator.variables['dexterity_type_fti_file_name'] == 'SpecialTask' # NOQA: E501 + assert configurator.variables['dexterity_type_name_klass'] == 'SpecialTask' + assert configurator.variables['dexterity_type_name_normalized'] == 'special_task' # NOQA: E501 + assert configurator.target_directory.endswith('/collective.todo/src/collective/todo') # NOQA: E501 + + configurator = Configurator( + template='bobtemplates.plone:content_type', + target_directory='collective.foo.bar', + bobconfig={ + 'non_interactive': True, + }, + variables={ + 'dexterity_type_name': 'special task', + }, + ) + content_type.prepare_renderer(configurator) + assert configurator.variables['dexterity_type_name'] == 'special task' + assert configurator.variables['dexterity_type_fti_file_name'] == 'special_task' # NOQA: E501 + assert configurator.variables['dexterity_type_name_klass'] == 'SpecialTask' + assert configurator.variables['dexterity_type_name_normalized'] == 'special_task' # NOQA: E501 + assert configurator.target_directory.endswith('/collective.todo/src/collective/todo') # NOQA: E501 + + configurator = Configurator( + template='bobtemplates.plone:content_type', + target_directory='collective.foo.bar', + bobconfig={ + 'non_interactive': True, + }, + variables={ + 'dexterity_type_name': 'Special_Task', }, ) content_type.prepare_renderer(configurator) + assert configurator.variables['dexterity_type_name'] == 'Special_Task' + assert configurator.variables['dexterity_type_fti_file_name'] == 'Special_Task' # NOQA: E501 + assert configurator.variables['dexterity_type_name_klass'] == 'SpecialTask' + assert configurator.variables['dexterity_type_name_normalized'] == 'special_task' # NOQA: E501 + assert configurator.target_directory.endswith('/collective.todo/src/collective/todo') # NOQA: E501 def test_check_global_allow_true(): diff --git a/setup.py b/setup.py index ea26eef1..4f6f6827 100644 --- a/setup.py +++ b/setup.py @@ -49,6 +49,7 @@ 'mr.bob', 'lxml', 'stringcase', + 'case-conversion', 'colorama', ], setup_requires=[],